http://tyvj.cn/p/1057
先把每个主件的附件存储到fj数组,然后开一个isf数组存储第i个组件是否是附件
存储重量为wi,价值为vi
那么接下来有5种决策:
1 什么都不要
2 主件
3 主件+附件1
4 主件+附件2
5 主件+附件1+附件2
当然转移是在这个组件不是附件的情况下的。
由于价格都是10的倍数,可以将n和wi、vi都除以10,最后*10即可,减少循环量
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main ()
{
const int maxn = 32000 + 10;
const int maxm = 60 + 10;
int n,m;
scanf("%d%d", &n, &m);
int fj[maxm][3];
memset(fj, 0, sizeof(fj));
int wi[maxm], vi[maxm];
bool isf[maxm];memset(isf, 0, sizeof(isf));
for (int i=1;i<=m;i++)
{
int v,p,q;
scanf("%d%d%d", &v, &p, &q);
wi[i] = v/10, vi[i] = v * p/10;
if (q)
{
fj[q][0]++;
fj[q][fj[q][0]] = i;
isf[i] = true;
}
}
int f[maxn]; memset(f, 0, sizeof(f));
for (int i=1;i<=m;i++)
{
for (int j=n/10;j>=0;j--)
{
if (!isf[i]) {
if(j>=wi[i])
f[j] = max(f[j], f[j-wi[i]]+vi[i]);
if(j>=wi[i]+wi[fj[i][1]])
f[j] = max(f[j], f[j-wi[i]-wi[fj[i][1]]]+vi[i]+vi[fj[i][1]]);
if(j>=wi[i]+wi[fj[i][2]])
f[j] = max(f[j], f[j-wi[i]-wi[fj[i][2]]]+vi[i]+vi[fj[i][2]]);
if(j>=wi[i]+wi[fj[i][1]]+wi[fj[i][2]])
f[j] = max(f[j], f[j-wi[i]-wi[fj[i][1]]-wi[fj[i][2]]]+vi[i]+vi[fj[i][1]]+vi[fj[i][2]]);
}
}
}
printf("%d\n", f[n/10]*10);
return 0;
}