共有N个物品,每个物品体积为wight[i],价值为val[i],给你空间M,问最多可以拿多少价值的物品?
- 我们如果设dp[i][j]表示取前i种物品使得其占用空间不超过j的价值总和最优解,那么答案就是dp[n][m]
- 状态转移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-wight[i]]+val[i])要么不取要么取。
- 比如:
dp[3][7],如果不取,价值总和为dp[2][7],如果取了,假设这个物品重量为4,价值为5,那么就要考虑dp[2][3](取两个物品且空间不超过3的价值总和最优解–仔细想想吧)+5(取得该物品的价值) 是不是比dp[2][7]要大,这就是状态转移方程的意思。
放代码吧,大家自己看看,这个容易爆内存,滚动数组不会,但是我暂时还不是很清楚,后续再更新。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4;
int wight[maxn],val[maxn],dp[maxn][4*maxn];
int main()
{
int n,m;
cin>>n>>m;
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)cin>>wight[i]>>val[i];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
dp[i][j]=dp[i-1][j];
if(j>=wight[i])dp[i][j]=max(dp[i-1][j],dp[i-1][j-wight[i]]+val[i]);
}
}
cout<<dp[n][m]<<endl;
return 0;
}