|Tyvj|NOIP2006|动态规划|P1057 金明的预算方案

来源:互联网 发布:希腊神话知乎 编辑:程序博客网 时间:2024/04/30 09:43

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;}


0 0