【NOIP2006】金明的预算方案 背包DP


【NOIP2006】金明的预算方案 背包DP_第1张图片

样例输入 Sample Input
1000 5

800 2 0 

400 5 1

300 5 1

400 3 0

500 2 0

样例输出 Sample Output
2200

图文并茂2333【不

一个简单的01背包变形。本来我想当挑附件的时候看看能不能挑主件,结果好像不能重复选同一个主件…所以我们就可以存每个主件所保存的附件,每次枚举取0,1,2个附件,然后就A了。

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int size=100010;
struct item{
    int v,p,q;
}l[size];

int dp[size];

vector<int> q[233];

int main()
{
    int v,n;
    scanf("%d%d",&v,&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&l[i].v,&l[i].p,&l[i].q);
        q[l[i].q].push_back(i);
    }

    for(int i=1;i<=n;i++)
    {
        if(l[i].q) continue;
        for(int j=v;j>=0;j--)
        {
            if(j>=l[i].v)
                dp[j]=max(dp[j],dp[j-l[i].v]+l[i].v*l[i].p);
            if(q[i].size()>0&&j>= l[i].v + l[q[i][0]].v)
                dp[j]=max(dp[j],dp[ j-l[i].v - l[q[i][0]].v ] + l[i].v*l[i].p + l[q[i][0]].v*l[q[i][0]].p);
            if(q[i].size()>1&&j>= l[i].v + l[q[i][0]].v + l[q[i][1]].v)
                dp[j]=max(dp[j],dp[ j-l[i].v - l[q[i][0]].v - l[q[i][1]].v] + l[i].v*l[i].p + l[q[i][0]].v*l[q[i][0]].p + l[q[i][1]].v*l[q[i][1]].p);
            if(q[i].size()>1&&j>= l[i].v + l[q[i][1]].v)
                dp[j]=max(dp[j],dp[ j-l[i].v - l[q[i][1]].v ] + l[i].v*l[i].p + l[q[i][1]].v*l[q[i][1]].p);
        }
    }
    printf("%d\n",dp[v]);
    return 0;
}
/*
2000 10
500 1 0
300 5 1
400 5 1
400 4 0
200 5 0
400 3 5
500 4 5
400 4 0
320 2 0
410 3 0

*/

你可能感兴趣的:(dp)