• HDU3033 分组背包 xingxing在努力


      这道题的意思是有K中品牌的鞋N个,每种品牌会有多个不同款式的鞋, 一个收藏家要收藏这些鞋,对于他来说这些鞋有一个估价,除此之外这些鞋也有标价, 且收藏家不会收藏多于一个的一种品牌同一款式的鞋, 且收藏家必须要至少收藏一种品牌的鞋一个,问收藏家拿着M块钱买回来鞋的估价最大是多少??不存在的话就输出impossible..这个题乍一看是一个分组背包的题, 但是与传统的分组背包所不同的是这个题要求每组至少选一个物品,而传统的是每组中至多选一个,那我们先看看传统的多重背包的状态方程f[j] = max(f[j], f[j-w]+v),这样的方程由于max第一项的存在可能会导致有一组中一个物品都没选, 因此我们应该禁止这种状态的转移建立新的状态方程。。考虑每一组中的一个鞋, dp[i][j]表示在前i个品牌的鞋中收藏家用j块钱恰好能得到的最大估价, 那么 dp[i][j] = max(dp[i-1][j-w[k]]+v[k], dp[i][j-w[k]]+v[k]),  那么答案就是max(dp[K][j]) k = 0-M; 实现的时候应该注意初始状态应该设dp[0][0] = 0;其他为负无穷或者-1或者其他无意义的负数,表示该状态无效。递推的时候也应该注意, 具体细节看代码:

    Wa点:1.递推式的推导     2.注意递推式的顺序    3:初始化

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    
    using namespace std;
    const int inf = 0x3f3f3f3f;
    
    int N, M, K;
    struct Wu
    {
        int b, c;
        Wu(){}
        Wu(int b, int c):b(b), c(c) {}
    };
    vector<Wu> wu[15];
    int f[12][100000 + 100];                //钱数为j时的最大价值
    
    int main()
    {
        while(scanf("%d%d%d", &N, &M, &K) == 3)
        {
            for(int i=1; i<=K; i++)
                wu[i].clear();
            for(int i=1; i<=N; i++)
            {
                int t, a, b;
                scanf("%d%d%d", &t, &a, &b);
                wu[t].push_back(Wu(a, b));    
            }
            /*for(int i=1; i<=K; i++)
            {
                printf("K = %d:", i);
                for(int j=0; j<wu[i].size(); j++)
                    printf("%d %d", wu[i][j].b, wu[i][j].c);
                printf("
    ");
            }*/
            memset(f, -1, sizeof(f));
            f[0][0] = 0;                                 
            //for(int i=0; i<=K; i++) f[i][0] = 0;
            for(int i=1; i<=K; i++)
                for(int k=0; k<wu[i].size(); k++)    //考虑第i组的第K个物品
                {
                    //printf("wu[%d].size = %d
    ", i, wu[i].size());
                    for(int j=M; j>=wu[i][k].b; j--)
                    {
                        if(f[i][j-wu[i][k].b] >= 0)                         //这个必须放到前面   否则会出错。。discuss里面有坑爹数据
                            f[i][j] = max(f[i][j], f[i][j-wu[i][k].b]+wu[i][k].c); 
                        if(f[i-1][j-wu[i][k].b] >= 0) 
                            f[i][j] = max(f[i][j], f[i-1][j-wu[i][k].b]+wu[i][k].c);
                    }
                /*    for(int tp=0; tp<=M; tp++)
                        printf("%d ", f[i][tp]);
                    printf("
    ");*/
                }
            bool flog = false;
            int res = 0;
            for(int i=M; i>=0; i--)  
                if(f[K][i] >= 0)  
                {
                    flog = true;
                    res = max(res, f[K][i]);
                }
            if(!flog)
                printf("Impossible
    ");
            else 
                printf("%d
    ", res);
        }
        return 0;
    }
  • 相关阅读:
    JHipster
    Integrating Jenkins and Apache Tomcat for Continuous Deployment
    What is the difference between apache tomcat deployer and core version?
    JEECG--去掉(增加)登陆页面验证码功能
    Protobuf一例
    进程间通信之POSIX信号量
    进程间通信之共享存储
    进程间通信之信号量
    进程间通信之消息队列
    进程间通信之XSI IPC
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5014197.html
Copyright © 2020-2023  润新知