UVALive - 4256 Salesmen (简单DP)

题意: 给定一个包含n个点的无向连通图和一个长度为L的序列A,你的任务是修改尽量少的数,使序列中任意两个相邻数或者相同,或者对应图中相邻的两个点。


思路:dp【i】【j】 第i个数为j时的最小修改数。


状态想到了,题目就很好写了。。。转移方程也ok的


#include
using namespace std;
const int N = 222;
int G[N][N],a[N],dp[N][N];
int main()
{
    ios::sync_with_stdio(false);
    int T,n,m,i,j,k;
    int u,v;
    cin>>T;
    while(T--) {
        cin>>n>>m;
        memset(G,0,sizeof(G));
        for(i=1;i<=m;i++) {
            cin>>u>>v;
            G[u][v]=G[v][u]=1;
        }
        cin>>m;
        for(i=1;i<=m;i++) cin>>a[i];
        for(i=1;i<=m;i++) {
            for(j=1;j<=n;j++)
                dp[i][j]=m;
        }
        for(i=1;i<=n;i++) dp[1][i]=1;
        dp[1][a[1]]=0;
        int ans=m;
        for(i=2;i<=m;i++) {
            for(j=1;j<=n;j++) {
                for(k=1;k<=n;k++) {
                    if(a[i]==j) {
                        if(j==k || G[j][k]) dp[i][j]=min(dp[i][j],dp[i-1][k]);
                    }
                    else {
                        if(j==k || G[j][k]) dp[i][j]=min(dp[i][j],dp[i-1][k]+1);
                    }
                }
                if(i==m) ans=min(ans,dp[m][j]);
            }
        }
        cout<



你可能感兴趣的:(UVa,DP)