zoukankan      html  css  js  c++  java
  • 【题解】P1064 [NOIP2006 提高组] 金明的预算方案

    P1064 [NOIP2006 提高组] 金明的预算方案

    与传统01背包不同的是,每个主件不再是只有选/不选两种情况,由于还带有0/1/2个附件,所以每个主件一共有如下种情况:

    没有附件:

    不选主件/选主件(价格允许的话)

    有一个附件:

    不选主件/选主件(价格允许的话)/选主件和附件(价格允许选二者的话)

    有两个附件:

    不选主件/选主件(价格允许的话)/选主件和附件A(价格允许选二者的话)/选主件和附件B(价格允许选二者的话)/选主件和附件A和附件B(价格允许选二者的话)

    这个题的特性是附件的数量少,只有0/1/2个,因此我们可以把附件涵盖在主件内处理而不用单独考虑附件的选择条件。

    坑点:由于附件不单独处理,所以如果开二维数组进行DP每次沿用上一行的状态的话会调用到附件的空状态。所以应该直接开一维数组然后倒序枚举总钱数。

    优化:由于物品价格都是10的倍数所以一开始就把n和v同时除以10最后总答案输出时再乘上10即可。

    int n, m, q;
    struct furniture{
        int v, p, ifmain;
        vi fujian;
    }fur[66];
    ll f[32010];
    int main(){
        n = rd(); m = rd(); n /= 10;
        for(int i = 1; i <= m; ++i){
            fur[i].v = rd(); fur[i].v /= 10;
            fur[i].p = rd();
            q = rd();
            if(q != 0){
                fur[q].fujian.pb(i);
                fur[i].ifmain = 0;
            }
            else fur[i].ifmain = 1;
        }
        for(int i = 1; i <= m; ++i){
            if(!fur[i].ifmain)  continue;
            for(int j = n; j >= 1; --j){
                if(j < fur[i].v)    continue;
                int kind = fur[i].fujian.size();
                if(kind >= 0){
                    f[j] = max(f[j], f[j - fur[i].v] + fur[i].v * fur[i].p);    
                }
                if(kind >= 1){
                    if(j >= fur[i].v + fur[fur[i].fujian[0]].v)    
                        f[j] = max(f[j], f[j - fur[i].v - fur[fur[i].fujian[0]].v] + fur[i].v * fur[i].p + fur[fur[i].fujian[0]].v * fur[fur[i].fujian[0]].p);
                }
                if(kind >= 2){
                    if(j >= fur[i].v + fur[fur[i].fujian[1]].v)
                        f[j] = max(f[j], f[j - fur[i].v - fur[fur[i].fujian[1]].v] + fur[i].v * fur[i].p + fur[fur[i].fujian[1]].v * fur[fur[i].fujian[1]].p);
                    if(j >= fur[i].v + fur[fur[i].fujian[0]].v + fur[fur[i].fujian[1]].v)
                        f[j] = max(f[j], f[j - fur[i].v - fur[fur[i].fujian[0]].v - fur[fur[i].fujian[1]].v] + fur[i].v * fur[i].p + fur[fur[i].fujian[0]].v * fur[fur[i].fujian[0]].p + fur[fur[i].fujian[1]].v * fur[fur[i].fujian[1]].p);
                }
            }
        }
        printf("%lld
    ", f[n] * 10);
    	return 0;
    }
    
  • 相关阅读:
    react的CSS中 :global的含义
    TypeScript中的问号 ? 与感叹号 ! 的含义
    移动端1px问题的解决方案
    原生js实现call,apply以及bind
    哪些场景不能使用箭头函数
    线性渐变、径向渐变以及圆锥渐变
    vue 开发中实现provide和inject实现依赖注入
    inline-block元素去除间隙
    clientWidth、offsetWidth、scrollWidth的区别
    session、token和cookie
  • 原文地址:https://www.cnblogs.com/ZhengkunJia/p/14983669.html
Copyright © 2011-2022 走看看