zoukankan      html  css  js  c++  java
  • Codevs 3269 混合背包

    3269 混合背包

      时间限制: 1 s    空间限制: 256000 KB    题目等级 : 钻石 Diamond

    题目描述 Description

    背包体积为V ,给出N个物品,每个物品占用体积为Vi,价值为Wi,每个物品要么至多取1件,要么至多取mi件(mi > 1) , 要么数量无限 , 在所装物品总体积不超过V的前提下所装物品的价值的和的最大值是多少?

    输入描述 Input Description

    第一行两个数N,V,下面N行每行三个数Vi,Wi,Mi表示每个物品的体积,价值与数量,Mi=1表示至多取一件,Mi>1表示至多取Mi件,Mi=-1表示数量无限

    输出描述 Output Description

    1个数Ans表示所装物品价值的最大值

    样例输入 Sample Input

    2 10

    3 7 2

    2 4 -1

    样例输出 Sample Output

    22

    数据范围及提示 Data Size & Hint

    对于100%的数据,V <= 200000 , N <= 200

     1 // 混合背包板子  我的哥 全TLE~~~~~~~~ 
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 using namespace std;
     6 #define N 210
     7 #define V 200010
     8 int n,v,f[V],wi[N],mi[N],vi[N];
     9 int main() 
    10 {
    11     scanf("%d%d",&n,&v);
    12     for(int i=1;i<=n;i++)
    13     {
    14         scanf("%d%d%d",&vi[i],&wi[i],&mi[i]);
    15         if(mi[i]==-1) mi[i]=v/vi[i];
    16     }
    17     for(int i=1;i<=n;i++)
    18     {
    19         for(int k=1;k<=mi[i];k++)
    20         {
    21             for(int j=v;j>=vi[i];j--)
    22               f[j]=max(f[j],f[j-vi[i]]+wi[i]);
    23         }
    24     }
    25     printf("%d",f[v]);
    26     return 0;
    27 }

    AC代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 #define N 210
     6 #define V 200010
     7 int n,v,f[V],wi[N],mi[N],vi[N];
     8 int main() 
     9 {
    10     scanf("%d%d",&n,&v);
    11     for(int i=1;i<=n;i++)
    12     {
    13         scanf("%d%d%d",&vi[i],&wi[i],&mi[i]);
    14         if(mi[i]==-1) mi[i]=v/vi[i];
    15     }
    16     for(int i=1;i<=n;i++)
    17     {
    18         int x=mi[i];
    19         for(int k=1;k<=x;k<<=1)//二分制优化   
    20         {
    21             for (int j=v;j>=vi[i]*k;j--)
    22                 f[j]=max(f[j],f[j-vi[i]*k]+wi[i]*k); 
    23             x-=k;   
    24         }
    25       if(x)
    26         for (int j=v;j>=vi[i]*x;j--)
    27           f[j]=max(f[j],f[j-vi[i]*x]+wi[i]*x);
    28     }
    29     printf("%d",f[v]);
    30     return 0;
    31 }

    再次说明一点,我将可以去无数次的物品的次数换成了v/vi[i]次(即通过总背包体积来限制他,这样就可以省掉一步)。。。

    二进制优化~~~依然的慢

    待解救~~~~~~~

    还有这题和队列有个毛关系~~

  • 相关阅读:
    js日期时间补零
    判断交换机性能好坏的九个因素
    [转]document.getElementById("...") is null
    ABAP数据库操作之操作语句Insert
    abap对excel处理
    选择屏幕搜索帮助
    Screen返回选择界面的问题
    ABAP 的TABLE CONTROL实践积累
    ALV的双击使用
    双击ALV调用事务代码并传入参数
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6217343.html
Copyright © 2011-2022 走看看