zoukankan      html  css  js  c++  java
  • hdu1059 dp(多重背包二进制优化)

    hdu1059

    题意,现在有价值为1、2、3、4、5、6的石头若干块,块数已知,问能否将这些石头分成两堆,且两堆价值相等。

    很显然,愚蠢的我一开始并想不到什么多重背包二进制优化```因为我连听都没有听过```不得不吐槽自己的知识面太窄```于是,我用了母函数写这题,母函数的做法并没有问题,但是由于这道题的数据很大,母函数轻轻松松就超时了,于是,我又很努力地在母函数循环的优化上面想出路,改改改,各种改之后依旧TLE,01背包的做法显然也是会超时的,DISCUSS里的母函数做法优化方式都是模上一个大质数,但很明显,只是因为数据较弱才会过的,因为没有人能保证被这个数模掉的那些部分是否可以平分,模掉之后剩下的数也很有可能就因此不能平分了所以这种优化肯定是不可取的。

    问过学长粗看了题解之后才知道原来还有一种叫多重背包的东西,学长推荐我看背包九讲,我看了之后才会做这个题目```

    多重背包其实本身也是01背包,但由于有多个价值相同的物品,所以有更加优化的解法就是用二进制优化,将相同价值的物品分为 20, 21 , 22 ,```个,最后再有一部分不能继续向二进制高阶划分的,将这些被划分的物品分别合成一个物品,那么就得到了价值为 1 倍的、2倍的、4倍的```物品,然后再按照01背包的做法,通过二进制数的加和可以实现物品的所有放入情况。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #define max(a,b) a>b?a:b
     4 int Va[100],We[100],n[7],dp[200000];
     5 
     6 int main(){
     7     int c=0;
     8     while(scanf("%d%d%d%d%d%d",&n[1],&n[2],&n[3],&n[4],&n[5],&n[6])!=EOF&&(n[1]!=0||n[2]!=0||n[3]!=0||n[4]!=0||n[5]!=0||n[6]!=0)){
     9     //    if(c)printf("
    ");
    10         printf("Collection #%d:
    ",++c);
    11         int i,j,sum=0,mid;
    12         for(i=1;i<=6;i++)sum+=i*n[i];
    13         if(sum%2){
    14             printf("Can't be divided.
    
    ");
    15             continue;
    16         }
    17         else mid=sum/2;
    18         memset(dp,-1,sizeof(dp));
    19         int count=0,temp;
    20         for(i=1;i<=6;i++){
    21             temp=1;
    22             while(n[i]>=temp){
    23                 Va[++count]=i*temp;
    24                 We[count]=temp;
    25                 n[i]-=temp;
    26                 temp*=2;
    27             }
    28             if(n[i]>0){
    29                 Va[++count]=i*n[i];
    30                 We[count]=n[i];
    31             }
    32         }
    33         dp[0]=0;
    34         for(i=1;i<=count;i++){
    35             for(j=mid;j>=Va[i];j--){
    36                 if(dp[j-Va[i]]>=0){
    37                     dp[j]=max(dp[j],dp[j-Va[i]]+We[i]);
    38                 }
    39             }
    40         }
    41         if(dp[mid]>0)printf("Can be divided.
    
    ");
    42         else printf("Can't be divided.
    
    ");
    43     }
    44     return 0;    
    45 }
    View Code
  • 相关阅读:
    Python AttributeError: module 'sys' has no attribute 'setdefaultencoding'
    Python reload(sys) NameError: name 'reload' is not defined
    Python reload(sys) NameError: name 'reload' is not defined
    Python 语法错误 except Exception, e: ^ SyntaxError: invalid syntax
    Python 语法错误 except Exception, e: ^ SyntaxError: invalid syntax
    Python 调用上级目录的文件
    Python 调用上级目录的文件
    Python 检查当前运行的python版本 python2 python3
    284 线程机制与事件机制:事件处理机制
    283 线程机制与事件机制:线程与进程,浏览器内核模块组成,js线程,定时器问题
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4290336.html
Copyright © 2011-2022 走看看