• HUST 1354 Rubiks


    背包。注释写详细了。

    本想这样写:每个组内各自做背包,然后组间做背包,但是由于这题M=10000,时间复杂度太大。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<iostream>
    #include<algorithm>
    #include<bitset>
    #include<functional>
    using namespace std;
    
    const int maxn = 10000 + 10;
    int n, m, g;
    
    vector<int>G[20];
    
    int cost[1000 + 10];
    int val[1000 + 10];
    int y[20];
    bool flag[1000 + 10];
    int dp1[10000 + 10];
    int dp2[10000 + 10];
    
    void init()
    {
        memset(flag, 0, sizeof flag);
        for (int i = 1; i <= g; i++) G[i].clear();
    }
    
    int main()
    {
        while (~scanf("%d%d", &n, &m)){
    
            for (int i = 1; i <= n; i++) scanf("%d", &cost[i]);
            for (int i = 1; i <= n; i++) scanf("%d", &val[i]);
            scanf("%d", &g);
            init();
            for (int i = 1; i <= g; i++)
            {
                int f;
                scanf("%d", &f);
                for (int j = 1; j <= f; j++)
                {
                    int id;
                    scanf("%d", &id);
                    G[i].push_back(id);
                    flag[id] = 1;
                }
                scanf("%d", &y[i]);
            }
    
            memset(dp1, 0, sizeof dp1);
    
            //没有组的归为一组
            for (int i = 1; i <= n; i++)
            {
                if (flag[i]) continue;
                for (int j = m; j >= cost[i]; j--)
                    dp1[j] = max(dp1[j], dp1[j - cost[i]] + val[i]);
            }
    
            for (int k = 1; k <= g; k++)
            {
                //此时dp2数组存储了之前的所有组合最优解
                for (int i = 1; i <= m; i++) dp2[i] = dp1[i];
    
                //接下来假设不买完这个组合内的魔方,这样DP的话事实上也存在买完的组合,但会被之后的dp2更新,所以不存在问题
                for (int s = 0; s < G[k].size(); s++)
                {
                    for (int j = m; j >= cost[G[k][s]]; j--)
                    {
                        dp1[j] = max(dp1[j], dp1[j - cost[G[k][s]]] + val[G[k][s]]);
                    }
                }
    
                //假设买完,用dp2更新
                int sum_cost = 0, sum_val = y[k];
                for (int s = 0; s < G[k].size(); s++)
                {
                    sum_cost = sum_cost + cost[G[k][s]];
                    sum_val = sum_val + val[G[k][s]];
                }
    
                for (int j = m; j >= sum_cost; j--)
                {
                    dp2[j] = max(dp2[j], dp2[j - sum_cost] + sum_val);
                }
    
                //然后dp1和dp2存下最大值
                for (int i = 0; i <= m; i++) dp1[i] = max(dp1[i], dp2[i]);
            }
    
            printf("%d
    ", dp1[m]);
        }
        return 0;
    }
  • 相关阅读:
    Spring 结合 Hibernate 配置 C3P0
    servlet直接调用spring的serivce方法
    http协议 web开发的应用 笔记
    一个让微软晕倒的中国人,绝对经典
    经典的上课插嘴
    教授说接吻
    在狼身上值得我们学习的十大处世哲学(经典)
    结婚前的暴强对话
    小笑话
    非一般的分手信
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5193635.html
Copyright © 2020-2023  润新知