zoukankan      html  css  js  c++  java
  • atcoder#073D(枚舉)

    題目鏈接: http://arc073.contest.atcoder.jp/tasks/arc073_b

    題意: 給出n, m兩個數, n是物品數目, m是背包容量, 接下來n行輸入, wi, vi分別爲第 i 件物品的體積和價值, 其中 w1 <= wi <= w1+3, 求背包所裝物品的最大價值;

    思路: 咋一看是到01背包, 但是m爲1e9, 按一般01背包寫法時間復雜度爲O(n*m), 肯定tle;

    這題和一般01背包還有一個不同的地方是 w1 <= wi <= w1+3, 那麼不難想到可以將物品根據 w 值分爲4類;

    顯然可以直接枚舉每類物品取了多少個, 然後取sum(vi)最大值即爲答案;

    注意:對於同類物品先取vi大的, 貪心嘛...

    代碼:

     1 #include <iostream>
     2 #include <algorithm>
     3 #define ll long long
     4 using namespace std;
     5 
     6 const int MAXN=1e2+10;
     7 ll a[MAXN], b[MAXN], c[MAXN], d[MAXN];
     8 ll av[MAXN], bv[MAXN], cv[MAXN], dv[MAXN];
     9 
    10 bool cmp(ll a, ll b){
    11     return a>b;
    12 }
    13 
    14 int main(void){
    15     ll n, m, x, y, cnt, ans=0;
    16     int indxa=1, indxb=1, indxc=1, indxd=1;
    17     cin >> n >> m;
    18     cin >> x >> y;
    19     cnt=x;
    20     a[indxa++]=y;
    21     for(int i=0; i<n-1; i++){
    22         cin >> x >> y;
    23         int cc=x-cnt;
    24         if(cc==0) a[indxa++]=y;
    25         else if(cc==1) b[indxb++]=y;
    26         else if(cc==2) c[indxc++]=y;
    27         else d[indxd++]=y;
    28     }
    29     sort(a+1, a+indxa, cmp);
    30     sort(b+1, b+indxb, cmp);
    31     sort(c+1, c+indxc, cmp);
    32     sort(d+1, d+indxd, cmp);
    33     for(int i=1; i<indxa; i++){
    34         av[i]=av[i-1]+a[i];
    35     }
    36     for(int i=1; i<indxb; i++){
    37         bv[i]=bv[i-1]+b[i];
    38     }
    39     for(int i=1; i<indxc; i++){
    40         cv[i]=cv[i-1]+c[i];
    41     }
    42     for(int i=1; i<indxd; i++){
    43         dv[i]=dv[i-1]+d[i];
    44     }
    45     for(int i=0; i<indxa; i++){
    46         ll cnt1=i*cnt;
    47         if(cnt1>m) break;
    48         for(int j=0; j<indxb; j++){
    49             ll cnt2=cnt1+j*(cnt+1);
    50             if(cnt2>m) break;
    51             for(int k=0; k<indxc; k++){
    52                 ll cnt3=cnt2+k*(cnt+2);
    53                 if(cnt3>m) break;
    54                 for(int l=0; l<indxd; l++){
    55                     ll cnt4=cnt3+(cnt+3)*l;
    56                     if(cnt4>m) break;
    57                     ll num=av[i]+bv[j]+cv[k]+dv[l];
    58                     ans=max(ans, num);
    59                 }
    60             }
    61         }
    62     }
    63     cout << ans << endl;
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    《洛谷P2296 寻找道路》
    《浙江科技学院第17届大学生程序设计竞赛:D:合并序列》
    《数论整理二》
    《洛谷P1282 多米诺骨牌》
    《洛谷P2140 小Z的电力管制》
    《洛谷P2798 爆弹虐场》
    Linux下运行C语言程序
    计算圆柱的底面积和体积
    将摄氏温度转化为华氏温度
    如果今天是星期二,那么100天后是星期几?
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/6789985.html
Copyright © 2011-2022 走看看