• [BZOJ] 1606: [Usaco2008 Dec]Hay For Sale 购买干草


    1606: [Usaco2008 Dec]Hay For Sale 购买干草

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 1335  Solved: 989
    [Submit][Status][Discuss]

    Description

        约翰遭受了重大的损失:蟑螂吃掉了他所有的干草,留下一群饥饿的牛.他乘着容量为C(1≤C≤50000)个单位的马车,去顿因家买一些干草.  顿因有H(1≤H≤5000)包干草,每一包都有它的体积Vi(l≤Vi≤C).约翰只能整包购买,
    他最多可以运回多少体积的干草呢?

    Input

        第1行输入C和H,之后H行一行输入一个Vi.

    Output

     
        最多的可买干草体积.

    Sample Input

    7 3 //总体积为7,用3个物品来背包
    2
    6
    5


    The wagon holds 7 volumetric units; three bales are offered for sale with
    volumes of 2, 6, and 5 units, respectively.

    Sample Output

    7 //最大可以背出来的体积

    HINT

    Buying the two smaller bales fills the wagon.

    Source

    Silver

    Analysis

    针对性优化的背包类DPqwq

    一开始口胡了一个贪心(降序排序后枚举最大值,然后开始遍历arr往addup里塞草包,如果当前值不合法就跳过找下一个值),居然过了!!!

    好吧,还是被CZL一波Hack... 果然是数据太水

    后来被LLQ一波对拍打出了问题所在:

    如果正解有不连续的元素,贪心会被轻松卡掉(比如5 4 3 2,以上策略优先选5+4然后跳过5)

    Code

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #define maxn 100000
     5 using namespace std;
     6 
     7 int arr[maxn],n,T,ans;
     8 
     9 bool cmp(const int a,const int b){
    10     return a>b;
    11 }
    12 
    13 int main(){
    14     scanf("%d%d",&T,&n);
    15     
    16     for(int i = 1;i <= n;i++){
    17         scanf("%d",&arr[i]);
    18     }
    19     
    20     sort(arr+1,arr+1+n,cmp);
    21     
    22     for(int i = 1;i <= n;i++){
    23         int addup = 0;
    24         for(int j = i;j <= n;j++){
    25             if(addup+arr[j] <= T){
    26                 addup += arr[j];
    27             }
    28         }
    29         ans = max(ans,addup);
    30     }
    31     
    32     printf("%d",ans);
    33     
    34     return 0;
    35 }
    神奇的贪心版本
     1 #include<cstdio>
     2 #include<iostream>
     3 #define maxn 1000000
     4 using namespace std;
     5 
     6 int DP[maxn],n,m,cnt;
     7 
     8 int main(){
     9     
    10     scanf("%d%d",&n,&m);
    11     
    12     for(int i = 1;i <= m;i++){
    13         scanf("%d",&cnt);
    14         DP[cnt] = 1;
    15         for(int j = n;j >= cnt;j--){
    16             DP[j] = DP[j]|DP[j-cnt];
    17         }
    18     }
    19     
    20     int ans = n;
    21     while(!DP[ans]) ans--;
    22     
    23     printf("%d",ans);
    24     
    25     return 0;
    26 }
    针对性优化背包版本
    转载请注明出处 -- 如有意见欢迎评论
  • 相关阅读:
    PHP7中php.ini、php-fpm和www.conf的配置(转)
    Linux下查看nginx、mysql、php的安装路径和编译参数
    Skip List(跳跃表)原理详解与实现【转】
    offset宏的讲解【转】
    Linux内核中的常用宏container_of其实很简单【转】
    Linux内核同步原语之原子操作【转】
    创建与合并分支【转】
    Git远程操作详解【转】
    【项目管理】git和码云的使用【转】
    Git和Github简单教程【转】
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7460523.html
Copyright © 2020-2023  润新知