zoukankan      html  css  js  c++  java
  • [CF808E] Selling Souvenirs(dp,背包)

    题目链接:http://codeforces.com/contest/808/problem/E

    题意:就是01背包,但是物品的重量只有1 2 3三种,背包容量会超大。

    三种重量按照价值从大到小排序,dp数组记录当前1、2重量的使用状态以及当前价值。更新完dp后,维护重量为3的物品的前缀和,再扫一遍,看看能不能用重量为3的前k个替换,更新最大值就行了。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long LL;
     5 typedef struct Node {
     6     int a, b;
     7     LL v;
     8 }Node;
     9 
    10 const int maxn = 300200;
    11 LL n, w;
    12 LL bag[4][maxn];
    13 LL sum[maxn];
    14 Node dp[maxn];
    15 int a, b, c;
    16 
    17 int main() {
    18     freopen("in", "r", stdin);
    19     int x;
    20     LL y;
    21     while(~scanf("%I64d%I64d",&n,&w)) {
    22         a = b = c = 0;
    23         memset(sum, 0, sizeof(sum));
    24         for(int i = 0; i < n; i++) {
    25             scanf("%d%I64d",&x,&y);
    26             if(x == 1) bag[1][++a] = y;
    27             if(x == 2) bag[2][++b] = y;
    28             if(x == 3) bag[3][++c] = y;
    29         }
    30         sort(bag[1]+1, bag[1]+a+1, greater<LL>());
    31         sort(bag[2]+1, bag[2]+b+1, greater<LL>());
    32         sort(bag[3]+1, bag[3]+c+1, greater<LL>());
    33         for(int i = 1; i <= c; i++) sum[i] = sum[i-1] + bag[3][i];
    34         dp[0] = Node{0,0,0};
    35         for(int i = 1; i <= w; i++) {
    36             dp[i] = dp[i-1];
    37             if(dp[i-1].a < a && dp[i-1].v + bag[1][dp[i-1].a+1] > dp[i].v) {
    38                 dp[i] = dp[i-1];
    39                 dp[i].v += bag[1][dp[i-1].a+1];
    40                 dp[i].a++;
    41             }
    42             if(i >= 2 && dp[i-2].b < b && dp[i-2].v + bag[2][dp[i-2].b+1] > dp[i].v) {
    43                 dp[i] = dp[i-2];
    44                 dp[i].v += bag[2][dp[i-2].b+1];
    45                 dp[i].b++;
    46             }
    47             // if(i >= 2 && dp[i-2].a + 1 < a && dp[i-1].v + bag[1][dp[i-1].a+1] + bag[1][dp[i-1].a+2] > dp[i].v) {
    48             //     dp[i] = dp[i-2];
    49             //     dp[i].v += bag[1][dp[i-1].a+1] + bag[1][dp[i-1].a+2];
    50             //     dp[i].a += 2;
    51             // }
    52             // if(i >= 3 && dp[i-3].c < c && dp[i-3].v + bag[3][dp[i-3].c+1] > dp[i].v) {
    53             //     dp[i] = dp[i-3];
    54             //     dp[i].v += bag[3][dp[i-3].c+1];
    55             //     dp[i].c++;
    56             // }
    57             // if(i >= 3 && dp[i-3].a < a && dp[i-3].b < b && dp[i-3].v + bag[1][dp[i-3].a+1] + bag[2][dp[i-3].b+1] > dp[i].v) {
    58             //     dp[i] = dp[i-3];
    59             //     dp[i].v += bag[1][dp[i-3].a+1] + bag[2][dp[i-3].b+1];
    60             //     dp[i].a++; dp[i].b++;
    61             // }
    62             // if(i >= 3 && dp[i-3].a + 2 < a && dp[i-3].v + bag[1][dp[i-3].a+1] + bag[1][dp[i-3].a+2] + bag[1][dp[i-3].a+3] > dp[i].v) {
    63             //     dp[i] = dp[i-3];
    64             //     dp[i].v += bag[1][dp[i-3].a+1] + bag[1][dp[i-3].a+2] + bag[1][dp[i-3].a+3];
    65             //     dp[i].a += 3;
    66             // }
    67         }
    68         LL ret = dp[w].v;
    69         for(int i = 1; i <= c; i++) {
    70             if(w >= i * 3) ret = max(ret, sum[i] + dp[w-3*i].v);
    71         }
    72         printf("%I64d
    ", ret);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    Linux scp、ssh命令
    Linux ps、top、free、uname命令
    适配器模式
    Linux不能进入图形化界面运行yum不管用
    SpringMVC 测试 mockMVC
    Idea和Git集成,并且Git管理不同的秘钥,idea分别提交项目到GitLab和GitHub
    多线程
    Java中Volatile关键字详解
    Spring事务管理--(二)嵌套事物详解
    jConsole, jVisualvm, btrace 区别和联系
  • 原文地址:https://www.cnblogs.com/kirai/p/6861787.html
Copyright © 2011-2022 走看看