UVA624(dp记录路径问题)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=565
根据01背包二维数组的动态转移方程dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]),可以知道,dp[i][j]的状态和dp[i-1][j]、dp[i-1][j-v[i]]有关,于是,在记录路径的时候,要是dp[i][j]==dp[i-1][j],说明,这条路没有走向dp[i-1][j-v[i]],这时,可以另开一个数组a[i][j],当dp[i][j]在动态转移时,==dp[i-1][j],则a[i][j]=0,否则a[i][j]=1;然后对数组a[i][j]进行回溯即可,具体看代码
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; #define max(x,y) (x>y? x:y) int dp[13000],a[1000][1000],w[13000],f[10000],count=0; void print(int n,int m) { if(n==0) return; if(a[n][m]==0) print(n-1,m); else { print(n-1,m-w[n]); f[count++]=w[n]; } } int main() { int n,m; while(scanf("%d%d",&m,&n)>0) { int i; for(i=1;i<=n;i++) scanf("%d",&w[i]); memset(dp,0,sizeof(dp)); memset(a,0,sizeof(a)); a[0][0]=1; for(i=1;i<=n;i++) { for(int j=m;j>=w[i];j--) { dp[j]=max(dp[j],dp[j-w[i]]+w[i]); if(dp[j]==dp[j-w[i]]+w[i]) a[i][j]=1; } } count=0; print(n,m); for(i=0;i<count;i++) { printf("%d ",f[i]); } printf("sum:%d\n",dp[m]); } return 0; }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。