完全背包的状态转移方程:
代码解释:
- 先说明一下,没有经过空间优化的DP数组是二维的,dp[i][j]表示遍历到前i个物品,且总的空间消耗为j时候的最大价值
- 经过空间优化后,dp数组是一维的,dp[j]表示总的空间消耗为j时的最大价值
#include <bits/stdc++.h>
#define maxn 10005
#define maxv 10000005
using namespace std;
int V,n;
long long c[maxn];//第i种物品的空间花费
long long v[maxn];//第i种草药的价值
long long dp[maxv];
int main(){
cin>>V>>n;//V是背包的体积,n是物品的数量
for(int i=0;i<n;i++){
cin>>c[i]>>v[i];
}
//虽然看起来难以理解,这样为什么就可以变成dp[i-1][j]和dp[i][j-c[i]]+v[i]之间的比较了呢?
//是这样的,在第i次外循环中,相当于更新了一遍dp[i][j];然后在第i+1次循环中,就变成了对dp[i+1][j]的循环,对于dp[j]而言,由于在这次循环中,是第一次到达这个j值,所以它的值仍然是上一个i循环中的值,也就是dp[i][j];而对于dp[j-c[i]]而言,则是第二次访问这个值,也就是说在第i+1轮次的循环中已经更新过了,所以也就是dp[i+1][j-c[i]]
for(int i=0;i<n;i++){
for(int j=c[i];j<=V;j++){
dp[j]=max(dp[j],dp[j-c[i]]+v[i]);
}
}
printf("%lld",dp[V]);
}