【洛谷P1064】金明的预算方案

大概。。。逆向思维?

链接

第一遍想的是按附件处理主件,这样的话可能会买很多个主件。维护的话应该是有办法的,只是不太好搞。

于是我们考虑重点维护主件,按主件处理附件,无非就是五种情况。

1.不选

2.只要主件

3.要主件和附件1

4.要主件和附件2

5.金明才做选择,我全都要!

因为这个题数据构成比较简单,所以结构体处理一波,01背包搞一搞就过了。

(我还考虑过跑最长路,真不知道一天到晚瞎想些什么啊)

(感谢GNAQ帮忙纠错,最开始因为复制粘贴哇了一个点,以后真的尽力不麻烦别人qwq)

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#define maxn 205
using namespace std;
int m,n;
struct ob{
    int v,w,k,p[2];
}e[maxn];
int dp[32005];
int main()
{
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&e[i].v,&e[i].w,&e[i].k);
        if(e[i].k){
          if(!e[e[i].k].p[0])
            e[e[i].k].p[0]=i;
          else e[e[i].k].p[1]=i;
        } 
    }
    for(int i=1;i<=n;i++)
    for(int j=m;e[i].w!=0,j>=e[i].v;j--)
    { 
        if(!e[i].k)
        {
            int p1=e[i].p[0],p2=e[i].p[1];
            dp[j]=max(dp[j],dp[j-e[i].v]+e[i].v*e[i].w);
            if(j>=e[i].v+e[p1].v)dp[j]=max(dp[j],dp[j-e[i].v-e[p1].v]+e[i].v*e[i].w+e[p1].v*e[p1].w);
            if(j>=e[i].v+e[p2].v)dp[j]=max(dp[j],dp[j-e[i].v-e[p2].v]+e[i].v*e[i].w+e[p2].v*e[p2].w);
            if(j>=e[i].v+e[p1].v+e[p2].v)
                dp[j]=max(dp[j],dp[j-e[i].v-e[p1].v-e[p2].v]+e[i].v*e[i].w+e[p1].v*e[p1].w+e[p2].v*e[p2].w);
        }
    }
    cout<<dp[m];
}

猜你喜欢

转载自blog.csdn.net/Sakura_Chiyo/article/details/82354846