解决背包问题的第一步就是先找到背包的容积还有物品价值和单个体积。。
01背包:
状态转移方程:dp[i + 1][j ] =max(dp[i ][j ]; dp[i ][j w[i ]] + v[i ]) 其他
=dp[i ][j ] (j < w[i ])
核心代码:
int dp[ MAXN ];
for (int i=0;i<n;i++)
for (int j=W;j >=w[i];j --)
dp[j]= max (dp[j],dp[j-w[i]]+ v[i]);
printf ("%d\n",dp[W]);
//或者:
for (int i=0;i<n;i++)
for (int j=0;j <=W;j++)
if(j<w[i])
dp[i +1][ j]= dp[i][j];
else
dp[i +1][ j]= max (dp[i][j],dp[i][j-w[i]]+ v[i]);
printf ("%d\n",dp[n][W]);
完全背包:
核心代码1:
for(int i=0;i<n;i++) for(int j=0;j<=W;j++) if(j<w[i]) dp[i+1][j]=dp[i][j]; else dp[i+1][j]=max(dp[i][j],dp[i+1][j-w[i]]+v[i]);//有一处和01背包不同 printf("%d\n",dp[n][W]);
核心代码2:
int dp[MAXN]; for(int i=0;i<n;i++) for(int j=w[i];j<=W;j++) //01背包是逆序,这里数顺序 dp[j]=max(dp[j],dp[j-w[i]]+v[i]); printf("%d\n",dp[W]);
多重背包:
核心代码(二进制优化)
就是将每一个物品的数目以二进制的形式拆分成一块一块的,比如10可以拆成1,2,4,3。这些数可以组建小于等于10的任意数。
for(int i=1;i<=n;i++) { int a,b,c; cin>>a>>b>>c; for(int k=1;k<=c;k<<=1){ w[num]=k*a; v[num++]=k*b; c-=k; } if(c>0) { w[num]=c*a; v[num++]=c*b; } } for(int i=1;i<num;i++){ for(int j=m;j>=w[i];j--){ dp[j]=max(dp[j],dp[j-w[i]]+v[i]); } }
浙公网安备 33010602011771号