⬅ 返回
1、闫氏DP分析法

2、例题
3、代码
3.1、二维dp
#include <iostream>
using namespace std;
const int N = 1e4;
int dp[N][N];//dp[i][j] 表示 前i组 在 容量为j 的条件下的最大价值
int v[N][N],w[N][N];
int ct[N];//记录每一组有多少个物品
int n,m;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int s;
cin>>s;
ct[i]=s;
for(int j=1;j<=s;j++)
{
int a,b;
cin>>a>>b;
v[i][j]=a;
w[i][j]=b;
}
}
for(int i=1;i<=n;i++)//n组
{
for(int j=0;j<=m;j++)
{
dp[i][j]=dp[i-1][j];//不选
for(int k=1;k<=ct[i];k++)//遍历该组的物品
{
if(v[i][k]<=j)
dp[i][j]=max(dp[i][j],dp[i-1][j-v[i][k]]+w[i][k]);
}
}
}
cout<<dp[n][m]<<endl;
}
3.2、一维优化
#include <iostream>
using namespace std;
const int N = 1e4;
int dp[N];//dp[i][j] 表示容量为j 的条件下的最大价值
int v[N][N],w[N][N];
int ct[N];//记录每一组有多少个物品
int n,m;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int s;
cin>>s;
ct[i]=s;
for(int j=1;j<=s;j++)
{
int a,b;
cin>>a>>b;
v[i][j]=a;
w[i][j]=b;
}
}
for(int i=1;i<=n;i++)//n组
{
for(int j=m;j>=0;j--)//容量从大到小 因为要用上一轮的数据
//若用的是这一轮的数据来回更新那就是完全背包
{
for(int k=1;k<=ct[i];k++)//遍历该组的物品
{
if(v[i][k]<=j)
dp[j]=max(dp[j],dp[j-v[i][k]]+w[i][k]);
}
}
}
cout<<dp[m]<<endl;
}