zoukankan      html  css  js  c++  java
  • 【二进制优化-多重背包】zznu-oj-2120 : 安详--如何用尽钱币打赏主播获得最大好感度

    2120 : 安详

    题目描述

    spring最近喜欢上了B站新秀主播,身为顿顿吃黄焖鸡的土豪,当然要过去打赏一番,但是spring还是喜欢精打细算,所以在打赏的时候,想要掏出有限的钱,获得主播的最大好感。

    主播的好感值是通过送不同的礼物而提升不同,不同礼物的赠送,可以增加的好感值也是不同的,当然礼物的价格更是不同。

    输入

    输入第一行为两个整数n,m.分别表示有n种不同礼物(1e2)和总金钱数m(1e6),以下n行每行有三个数字,分别表示该礼物的个数(int)和价格(int)以及好感值(int)。 多实例

    输出

    求spring拿出的钱可以送出的最大好感值。

    样例输入

    复制
    2 10
    4 2 100
    2 4 100

    样例输出

    复制
    400

    多重背包解决思路:

     题目:有N种物品和一个容量为V的背包。第i种物品最多有num[i]件可用,每件容量是c[i],价值是w[i]。

    转换成01背包:二进制优化方法是:将第i种物品分成若干件物品,其中每件物品有一个系数,这件物品的容量和价值均是原来的容量和价值乘以这个系数。使这些系数分别为1,2,4,...,2^(k-1),(以及二进制尾数部分)num[i]-2^k+1,且k是满足num[i]-2^k+1>0的最大整数。例如,如果n[i]为13,就将这种物品分成系数分别为1,2,4,6的四件物品。

      

     1 #define N 10008
     2 #define M 1000008
     3 
     4 ll dp[M];
     5 struct node{
     6     ll c,w;  //c为cost,w为好感度
     7 }p[N];
     8 
     9 int main(){
    10 
    11     ll nn,m;
    12     while(scanf("%lld%lld",&nn,&m)!=EOF){
    13         int cnt=0;//拆分后的物品数
    14         ll t,c,w;
    15 
    16         for(int i=1;i<=nn;i++){
    17             scanf("%lld%lld%lld",&t,&c,&w);  //数量,花费,好感度
    18             int x=1;
    19             while(t-x>0){
    20                 t-=x;
    21                 p[++cnt].c=x*c;
    22                 p[cnt].w  =x*w;
    23                 x*=2;
    24             }
    25             p[++cnt].c=t*c; //跑完上面的循环后剩下t
    26             p[cnt].w=t*w;
    27         }
    28 
    29         memset(dp,0,sizeof(dp));
    30         for(int i=1;i<=cnt;i++){
    31             for(int j=m;j>=p[i].c;j--){  //花费自大到小
    32                 dp[j]=max(dp[j],dp[j-p[i].c]+p[i].w);
    33             }
    34         }
    35 
    36 
    37         printf("%lld
    ",dp[m]);
    38     }
    39 
    40     return 0;
    41 }
    42 #define N 10008
    43 #define M 1000008
    44 
    45 ll dp[M];
    46 struct node{
    47     ll c,w;  //c为cost,w为好感度
    48 }p[N];
    49 
    50 int main(){
    51 
    52     ll nn,m;
    53     while(scanf("%lld%lld",&nn,&m)!=EOF){
    54         int cnt=0;//拆分后的物品数
    55         ll t,c,w;
    56 
    57         for(int i=1;i<=nn;i++){
    58             scanf("%lld%lld%lld",&t,&c,&w);  //数量,花费,好感度
    59             int x=1;
    60             while(t-x>0){
    61                 t-=x;
    62                 p[++cnt].c=x*c;
    63                 p[cnt].w  =x*w;
    64                 x*=2;
    65             }
    66             p[++cnt].c=t*c; //跑完上面的循环后剩下t
    67             p[cnt].w=t*w;
    68         }
    69 
    70         memset(dp,0,sizeof(dp));
    71         for(int i=1;i<=cnt;i++){
    72             for(int j=m;j>=p[i].c;j--){  //花费自大到小
    73                 dp[j]=max(dp[j],dp[j-p[i].c]+p[i].w);
    74             }
    75         }
    76 
    77 
    78         printf("%lld
    ",dp[m]);
    79     }
    80 
    81     return 0;
    82 }
    View Code(头文件都私奔找对象去啦!)
  • 相关阅读:
    H
    并查集
    H
    Supermarket (贪心 并查集)
    H
    M
    N-Find a way
    HDU 4035 Maze
    #386. 【UNR #3】鸽子固定器
    P4688 [Ynoi2016]掉进兔子洞
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/9373008.html
Copyright © 2011-2022 走看看