第一次写有依赖的背包问题
哇 感觉好难啊
好不容易搞懂一点点
写个博客吧!
题目链接:https://www.luogu.org/problemnew/show/P1064
#include<iostream>
#include<cstring>
using namespace std;
struct aa
{
int v,p,q;
}a[60],pat[60][60];
int n,m,t[60],V[60][10],P[60][10],cnt[60],f[32000],ans,i,j,k;
int main()
{
cin>>n>>m;
for(i=1;i<=m;i++)
{
cin>>a[i].v>>a[i].p>>a[i].q;//输入
if(a[i].q!=0)//当他是附件时
{
t[a[i].q]++;//主件有多少附件
pat[a[i].q][t[a[i].q]].v=a[i].v;
pat[a[i].q][t[a[i].q]].p=a[i].p;
pat[a[i].q][t[a[i].q]].q=a[i].q;//替换输入
}
}
for(i=1;i<=m;i++)//当物品是附件时是直接跳过的
{
if(t[i]!=0)//选主件也选附件
{
memset(f,-1,sizeof(f)); //当f[i]==-1时表示这个体积下没有选任何一个附件(恰好背包)
f[0]=0;
for(j=1;j<=t[i];j++)//多重背包 对于这件物品的附件选择
for(k=n-a[i].v;k>=pat[i][j].v;k--)
if(f[k]<f[k-pat[i][j].v]+pat[i][j].v*pat[i][j].p&&f[k-pat[i][j].v]!=-1)
f[k]=f[k-pat[i][j].v]+pat[i][j].v*pat[i][j].p;
for(j=0;j<=n-a[i].v;j++)
if(f[j]!=-1)//有用的情况 选择了一个或多个附件
{
cnt[i]++;
V[i][cnt[i]]=j+a[i].v;
P[i][cnt[i]]=f[j]+a[i].v*a[i].p;//记录代替
}
}
if(a[i].q==0)//只选主件
{
cnt[i]++;
V[i][cnt[i]]=a[i].v;
P[i][cnt[i]]=a[i].p*a[i].v;//记录代替
}
}
memset(f,0,sizeof(f));
for(i=1;i<=m;i++)//分组背包 当物品是附件时是直接跳过的
for(j=n;j>=0;j--)
for(k=1;k<=cnt[i];k++)
if(j>=V[i][k])
f[j]=max(f[j],f[j-V[i][k]]+P[i][k]);
for(i=0;i<=n;i++)
ans=max(ans,f[i]);//求出最大值
cout<<ans<<endl;//输出
}