题目地址
金明的题都出烂了怎么我还在写。。。依赖性背包,把主件和它的附件看做一个集合,每个集合的决策只有5种:
1.全部不选
2.选主件
3.选主件和附件1
4.选主件和附件2
5.全选
把主件拉在一个数组计算
即珂。
蒟蒻的垃圾码风
:
//2020/2/16 TOSHIBA i3-2328 2.5Hz FILCO圣手2代 百乐V5 晨光K-35
# include <bits/stdc++.h>
using namespace std;
const int N=32010;
int n,m;
int w[N][3];
int c[N][3];
int sonk[N];
int dp[N];
int zhujian[N];
int zk=0;
//vector <int> son[N];
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') w=-1;
ch=getchar();
}
while(isdigit(ch))
{
s=(s<<1)+(s<<3)+ch-'0';
ch=getchar();
}
return s*w;
}
void Input()
{
n=read(),m=read();
for(int i=1;i<=m;i++)
{
int _w=read(),_c=read(),_q=read();
if(_q==0)
{
w[i][0]=_w;
c[i][0]=_c;
zhujian[++zk]=i;
}
else
{
++sonk[_q];
w[_q][sonk[_q]]=_w;
c[_q][sonk[_q]]=_c;
}
}
return ;
}
void solve()
{
int P;
for(int i=1;i<=zk;i++)
{
P=zhujian[i];
for(int j=n;j>=w[P][0];j--)
{
dp[j]=max(dp[j],dp[j-w[P][0]]+c[P][0]*w[P][0]); //No choose and Only choose
if(sonk[P]>=1&&j>=w[P][0]+w[P][1]) dp[j]=max(dp[j],dp[j-w[P][0]-w[P][1]]+c[P][0]*w[P][0]+c[P][1]*w[P][1]);
if(sonk[P]>=2&&j>=w[P][0]+w[P][2]) dp[j]=max(dp[j],dp[j-w[P][0]-w[P][2]]+c[P][0]*w[P][0]+c[P][2]*w[P][2]);
if(sonk[P]>=2&&j>=w[P][0]+w[P][1]+w[P][2]) dp[j]=max(dp[j],dp[j-w[P][0]-w[P][1]-w[P][2]]+c[P][0]*w[P][0]+c[P][1]*w[P][1]+c[P][2]*w[P][2]);
}
}
printf("%d\n",dp[n]);
return ;
}
int main(void)
{
Input();
solve();
return 0;
}
/*
每一次对于主件有5种决策:
1.屁都不选
2.选主件
3.选主件+附件1
4.选主件+附件2
5.我全都要
也就是对于每一个主件与附件集合的最优解,枚举每个集合,得到全局最优
*/