• ZOJ 3264 Present for MM


    寒假开始了···但是做题没有结束嘤···

    然后是dp专场嘤···


    题意:背包问题,给出背包容量和物品对数,每对物品都有特殊的关系:第一种关系是两个物品都取有价值,若只取一个则失去价值;第二种是两个物品只能取一个,都取则失去价值;第三种是只有当第一个被取时第二个才能被取,但可以单独取第一个物品。


    解法:第一种关系只要将两个物品看做一个物品就可以了,第二种关系是分组背包,第三种关系是有依赖背包,可以抽象为含有两个物品(第一个物品,第一个物品+第二个物品)的分组背包。最后都可以看做是分组背包。

    这题就坑在物品的w可以为0···嘤嘤嘤···


    代码:

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define LL long long
    using namespace std;
    struct node
    {
        int w, v;
        node(int a, int b)
        {
            w = a;
            v = b;
        }
        node() {}
    };
    vector <node> tre[10005];
    int dp[50005];
    int main()
    {
        int w, n;
        while(~scanf("%d%d", &w, &n))
        {
            for(int i = 0; i < 10005; i++)
                tre[i].clear();
            memset(dp, 0, sizeof(dp));
            w /= 100;
            int cnt = 0;
            for(int i = 0; i < n; i++)
            {
                int w1, v1, w2, v2, r;
                scanf("%d%d%d%d%d", &w1, &v1, &w2, &v2, &r);
                w1 /= 100;
                w2 /= 100;
                if(r == 1)//合并成一个物品
                    tre[cnt++].push_back(node(w1 + w2, v1 + v2));
                else if(r == 2)//分组背包
                {
                    tre[cnt].push_back(node(w1, v1));
                    tre[cnt++].push_back(node(w2, v2));
                }
                else//抽象成分组背包
                {
                    tre[cnt].push_back(node(w1, v1));
                    tre[cnt++].push_back(node(w1 + w2, v1 + v2));
                }
            }
            for(int i = 0; i < cnt; i++)//组
                for(int j = w; j >= 0; j--)
                {
                    int ret = -1;//一组内每个物品在容量为j时获得价值的最大值,因为物品的w可以为0,所以不能用dp数组直接求
                    for(int k = 0; k < tre[i].size(); k++)//每组的物品
                        if(j >= tre[i][k].w)
                            ret = max(ret, (dp[j - tre[i][k].w] + tre[i][k].v));
                    dp[j] = max(dp[j], ret);
                }
            printf("%d
    ", dp[w]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    顾问和注解
    正则
    GitHub 的简单使用
    JavaScript变态题目
    常用的Javascript设计模式
    HTML5 本地裁剪上传图片
    webpack 打包
    详解js闭包
    常用的Javascript设计模式
    call appiy
  • 原文地址:https://www.cnblogs.com/Apro/p/4303985.html
Copyright © 2020-2023  润新知