uva 1424 (dp专组G题)

链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36240

题意,

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

题解:

用矩阵a存图,如果i,j之间有边置a[i][j] = a[j][i] = 1,并把正对角线也置1,等价于点和它本身连线。

用数组f存给定的序列A

用dp[i][k]表示在第i位为k时需要修改的最小的次数。

则可知dp[0][i] = (f[i]!=i).

动态转移方程为dp[i][k] = min(dp[i][k],dp[i-1][j] + f[i] != k);其中j为1~n1中所有a[j][k] = 1的值;

最后dp[n-1][i](1<=i<=n1)中的最小值即为所求。

本题错点:(我自己的)

要注意边界范围。

代码如下:

#include
using namespace std;
const int maxn = 105;
const int INF = 0x3f3f3f3f;
int a[maxn][maxn];
int d[2*maxn][maxn];
int f[2*maxn];

int main(){
    int T;
    cin>>T;
    while(T--){
        int n1,n2;
        cin>>n1>>n2;
        memset(a,0,sizeof(a));
        for(int i = 1;i<=n1;i++)a[i][i] = 1;
        for(int i= 0;i>x>>y;
            a[x][y] = a[y][x] = 1;
        }
        int n;
        cin>>n;
        memset(d,INF,sizeof(d));
        for(int i = 0;i>f[i];
        for(int i = 1;i<=n1;i++)d[0][i] = (f[0] != i);
        for(int i = 1;i


你可能感兴趣的:(uva,dp)