• 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]次(即通过总背包体积来限制他,这样就可以省掉一步)。。。

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

    待解救~~~~~~~

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

  • 相关阅读:
    C代码优化的一些方法
    读书笔记之:C++程序设计原理与实践(其他)[+++]
    读书笔记之:C++ Primer Plus(第5版)
    使用SoapFormatter 类序列化
    C# 多线程学习系列
    winform中读取嵌入的xml文件
    使用Web Service上(服务器端访问)
    jquery ajax调用webservice
    ashx文件和HttpHandler
    以Window服务作为wcf的寄主
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6217343.html
Copyright © 2020-2023  润新知