zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Halcon HWindowControl 控件中图像的缩放与移动
    OpenCV cv::mean()函数详解
    OpenCV 霍夫变换(Hough Transform)
    OpenCV 图像分割
    OpenCV 使用ROI进行图像切割
    OpenCV 轮廓查找与绘制-最小外接矩形
    OpenCV 提取轮廓的凸包、外包矩形、最小外包矩形、最小外包圆
    KubeDL 加入 CNCF Sandbox,加速 AI 产业云原生化
    DataWorks 功能实践速览
    coredump 瘦身风云
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5193635.html
Copyright © 2011-2022 走看看