LA 2257 动态规划
题意:无向图中有n个点,编号1~n,可以从一点走到相邻某点,也可以原地不动,这样得到一条路径的描述。
例如下图所示的无向图中,路径[1 2 2 7 5 5 5 7 4]是错误的,因为2不能到达7, [1 2 2 4 5 5 5 7 4], [1 2 4 7 5 5 5 7 4], or [1 2 2 6 5 5 5 7 4]都是正确的,
定义两条路径A和B的距离dist(A, B) = sum d(ai, bi) ,其中若ai==bi, d(ai, bi)=1 否则d(ai, bi)=0。。
给定一条路径A,求一条正确路径B,使AB的距离 dist(A, B) 最小。
分析:dp(i, v)表示第 i 步为点 v 的最小距离,dp(i, v) = min dp(i-1,u)+t. (u到v有边,若Ai==v, t=0, 否则t=1.)
const int N = 105, M = 10000; int n, m; int a[N<<1], len;//错误路径 int dp[2][N<<1], p, q;//dp[i][j]表示第i个点为j的最小dist p q滚动数组 int head[N]; struct node{//边 int v, next; }e[M]; void DP(){ p = 0; memset(dp[p], 0, sizeof dp[p]); FOE(i, 1, len){ q = 1-p; memset(dp[q], -1, sizeof dp[q]); FOE(u, 1, n){ for(int j = head[u]; j!=-1; j=e[j].next){ int v = e[j].v; checkmin(dp[q][v], dp[p][u]+(a[i]!=v)); } } p = q; } int ans = -1; FOE(i, 1, n) checkmin(ans, dp[q][i]); printf("%d\n", ans); } int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif int T; scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); p = 0; memset(head, -1, sizeof head); FOR(i, 0, m){ int x, y; scanf("%d%d", &x, &y); e[p].v=y; e[p].next=head[x]; head[x]=p++; e[p].v=x; e[p].next=head[y]; head[y]=p++; } FOE(i, 1, n) {//到自己的边 e[p].v=i; e[p].next=head[i]; head[i]=p++; } scanf("%d", &len); FOE(i, 1, len) scanf("%d", &a[i]); DP(); } return 0; }