您的位置:首页 > 其它

uva 1424 (dp专组G题)

2016-05-02 18:12 453 查看
链接: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<bits/stdc++.h>
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<n2;i++){
int x,y;
cin>>x>>y;
a[x][y] = a[y][x] = 1;
}
int n;
cin>>n;
memset(d,INF,sizeof(d));
for(int i = 0;i<n;i++)cin>>f[i];
for(int i = 1;i<=n1;i++)d[0][i] = (f[0] != i);
for(int i = 1;i<n;i++){
for(int k = 1;k<=n1;k++){
for(int j = 1;j<=n1;j++){
if(a[k][j]){
d[i][k] = min(d[i][k],d[i-1][j]+(f[i]!=k));
}
}
//                cout<<i<<" "<<k<<" "<<d[i][k]<<endl;
}
}
int ans = INF;
for(int i = 1;i<=n1;i++){
ans = min(ans,d[n-1][i]);
}
cout<<ans<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva dp