//记忆化搜索+dfs
int rec(int i, int j) {
if (dp[i][j] >= 0)//已经计算过的就可以使用之前的值
return dp[i][j];
int res;
if (i == n)res = 0;//0-n-1,第n个当然不能放了
else if (j < w[i])res = rec(i + 1, j)//不能放的时候第i个最大价值等于i+1的
else res = max(rec(i + 1, j), rec(i + 1, j - w[i]) + v[i]);
return dp[i][j] = res;//记忆化
}
物品从0-n-1编号
for(int i=n-1;i>=0;i--)
for (int j = 0; j <= w; j++) {
if (j < w[i])
dp[i][j] = dp[i + 1][j];
else
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j - w[i]] + v[i]);
}
cout << dp[0][w] << endl;
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]);
}
}
cout << dp[n][w];
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]);
}
}
cout << dp[n] << endl;
dp[i+1][j]的计算中选k个的情况,与在dp[i+1][j-w[i]]中的k-1个情况完全相同,所以dp[i+1][j]可由dp[i+1][j-w[i]]的计算得到
max{dp[i][j-k*w[i]]+kv[i]|0<=k}
=max(dp[i][j],max{dp[i][j-k*w[i]]+kv[i]|k>=1})
=max(dp[i][j],max{dp[i][j-w[i]-k*w[i]]+k*v[i]|k>=0}+v[i])
=max(dp[i][j],dp[i+1][j-w[i]]+v[i])
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]);
}
}
cout << dp[n][w];
for (int i = 0; i < n; i++) {
for (int j = w[i]; j <= w; j++) {
dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
}
}
cout<<dp[w];
原文:https://www.cnblogs.com/ACMerLwy/p/11268704.html