有依赖的背包问题——金明的预算方案

题目:金明的预算方案
这是动态规划中的背包问题中的有依赖的背包问题。
幸好题目中说道:每个主件可以有0个、1个或2个附件。附件不再有从属于自己的附件。否则这题就变成了一个树形DP了。
状态表达:f[i] = 当v == i时的最大价值。
状态转移方程:

f[j] = std::max(f[j],f[j-num[i].w1]+num[i].c1);
                        if(j-num[i].w1-num[i].w2>=0)f[j] = std::max(f[j],f[j-num[i].w1-num[i].w2]+num[i].c1+num[i].c2);
                        if(j-num[i].w1-num[i].w3>=0)f[j] = std::max(f[j],f[j-num[i].w1-num[i].w3]+num[i].c1+num[i].c3);
                        if(j-num[i].w1-num[i].w2-num[i].w3>=0)f[j] = std::max(f[j],f[j-num[i].w1-num[i].w2-num[i].w3]+num[i].c1+num[i].c2+num[i].c3);

状态数量:nv
转移代价:O(1)
时间复杂度:O(nv)
空间复杂度:O(v)
附上代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>

class node
{
public:
        int w1,w2,w3;
        int c1,c2,c3;
}num[100];

int n,v,f[100001];

void init()
{
        std::cin>>v>>n;
        for(int i = 1;i<=n;i++)
        {
                int a,b,s;
                std::cin>>a>>b>>s;
                b *= a;
                if(s==0)
                {
                        num[i].w1 = a;
                        num[i].c1 = b;
                }
                else if(num[s].w2==0&&num[s].c2==0)
                {
                        num[s].w2 = a;
                        num[s].c2 = b;
                }
                else
                {
                        num[s].w3 = a;
                        num[s].c3 = b;
                }
        }
}

int get_ans()
{
        for(int i = 1;i<=n;i++)
                for(int j = v;j>=num[i].w1;j--)
                {
                        f[j] = std::max(f[j],f[j-num[i].w1]+num[i].c1);
                        if(j-num[i].w1-num[i].w2>=0)f[j] = std::max(f[j],f[j-num[i].w1-num[i].w2]+num[i].c1+num[i].c2);
                        if(j-num[i].w1-num[i].w3>=0)f[j] = std::max(f[j],f[j-num[i].w1-num[i].w3]+num[i].c1+num[i].c3);
                        if(j-num[i].w1-num[i].w2-num[i].w3>=0)f[j] = std::max(f[j],f[j-num[i].w1-num[i].w2-num[i].w3]+num[i].c1+num[i].c2+num[i].c3);
                }
        return f[v];
}

int main()
{
        init();
        std::cout<<get_ans();
        return 0;
}
posted @ 2017-05-23 16:59  leo101  阅读(338)  评论(0编辑  收藏  举报