• 采药


    采药(jdoj1049)

        题目大意:不同于NOIP的采药,这道题的描述都是一样的,只是数据范围有毒。

        注释:总时间和药的种类全是100,000,每种药的时间和价值不大于10。

          想法:如果想NOIP那道题一样用01背包跑的话,时间复杂度是O(10^10),显然会T掉,所以,我们想拓展一下别的方法,显然,极其容易注意到每种药物的时间和价值实在是太小了,所以在处理的过程中必定会有很多药物是一模一样的,所以,想到——多重背包。但是单纯的多重背包的时间复杂度是不发生改变的,所以我们极其容易想到一种优化——二进制优化。二进制的原理是一串2的每次加上剩余的数,是一定可以凑出所有的数的,这就是二进制优化的原理。说到这儿,这题就切了......

        最后,附上丑陋的代码......

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 int a[100100];
     7 int aa[20][20];
     8 int x[100];
     9 int cnt;
    10 void two(int k)//二进制优化
    11 {
    12     cnt=0;
    13     if(k==1)
    14     {
    15         x[++cnt]=1;
    16         return;
    17     }
    18     else if(k==0)
    19     {
    20         return;
    21     }
    22     else
    23     {
    24         k--;
    25         x[++cnt]=1;
    26         int now=1;
    27         while(1)
    28         {
    29             if(k>now*2)
    30             {
    31                 k-=now*2;
    32                 x[++cnt]=now*2;
    33                 now*=2;
    34             }
    35             else
    36             {
    37                 x[++cnt]=k;
    38                 return;
    39             }
    40         }
    41     }
    42 }
    43 int main()
    44 {
    45     int n,m;
    46     scanf("%d%d",&n,&m);
    47     int time,val;
    48     for(int i=1;i<=n;i++)
    49     {
    50         scanf("%d%d",&time,&val);
    51         aa[time][val]++;
    52     }
    53     for(int i=1;i<=10;i++)
    54     {
    55         for(int j=1;j<=10;j++)
    56         {
    57             memset(x,0,sizeof(x));//important ! important !! important !!!
    58             two(aa[i][j]);
    59             for(int ii=1;ii<=cnt;ii++)
    60             {
    61                 for(int jj=m;jj>=i*x[ii];jj--)
    62                 {
    63                     a[jj]=max(a[jj],a[jj-i*x[ii]]+x[ii]*j);
    64                 }
    65             }
    66         }
    67     }
    68     int minn=-1;
    69     for(int i=m;i>=1;i--) minn=max(minn,a[i]);
    70     printf("%d",minn);
    71 }

        小结:错误

            1.清数组。

        转载请注明:http://www.cnblogs.com/ShuraK/p/7853217.html

    | 欢迎来原网站坐坐! >原文链接<

  • 相关阅读:
    CSS中一个冒号和两个冒号有什么区别
    伪类元素实现可伸缩时间轴
    Gulp实现css、js、图片的压缩以及css、js文件的MD5命名
    for 循环进化史
    细谈sass和less中的变量及其作用域
    Vue2.0源码阅读笔记--双向绑定实现原理
    你所不知道的setTimeout
    前端COOKIE与SESSION的区别
    js移动端向左滑动出现删除按钮
    推荐几款屏幕录制工具(可录制GIF)
  • 原文地址:https://www.cnblogs.com/ShuraK/p/7853217.html
Copyright © 2020-2023  润新知