zoukankan      html  css  js  c++  java
  • 背包问题题目练习

    1.完全背包

    NYOJ 311

    完全背包

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:4
    描述

    直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的体积是c,价值是w。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。本题要求是背包恰好装满背包时,求出最大价值总和是多少。如果不能恰好装满背包,输出NO

    输入
    第一行: N 表示有多少组测试数据(N<7)。
    接下来每组测试数据的第一行有两个整数M,V。 M表示物品种类的数目,V表示背包的总容量。(0<M<=2000,0<V<=50000)
    接下来的M行每行有两个整数c,w分别表示每种物品的重量和价值(0<c<100000,0<w<100000)
    输出
    对应每组测试数据输出结果(如果能恰好装满背包,输出装满背包时背包内物品的最大价值总和。 如果不能恰好装满背包,输出NO)
    样例输入
    2
    1 5
    2 2
    2 5
    2 2
    5 1
    样例输出
    NO
    1
     1 /*
     2 虽然感觉这个题目好像要用long long ,才能过,但实际上用int就行,而且long long会超时
     3 */
     4 #define N 2008
     5 #include<iostream>
     6 using namespace std;
     7 #include<cstdio>
     8 #include<cstring>
     9 #define V 50008
    10 typedef long long ll;
    11 int f[V],val[N];
    12 int T,m,v,w[N];
    13 int main()
    14 {
    15     scanf("%d",&T);
    16     while(T--)
    17     {
    18         scanf("%d%d",&m,&v);
    19         for(int i=1;i<=m;++i)
    20           scanf("%d%I64d",&w[i],&val[i]);
    21         memset(f,-127,sizeof(f));
    22         f[0]=0;
    23         for(int i=1;i<=m;++i)
    24           for(int j=w[i];j<=v;++j)
    25           f[j]=max(f[j],f[j-w[i]]+val[i]);
    26         if(f[v]>0)printf("%I64d",f[v]);
    27         else printf("NO
    ");
    28     }
    29     return 0;
    30 }

    2.多重背包

    HDU - 2844

    Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u

    Status

    Description

    Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One day Hibix opened purse and found there were some coins. He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn't know the exact price of the watch.

    You are to write a program which reads n,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coins of value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can pay use these coins.

    Input

    The input contains several test cases. The first line of each test case contains two integers n(1 ≤ n ≤ 100),m(m ≤ 100000).The second line contains 2n integers, denoting A1,A2,A3...An,C1,C2,C3...Cn (1 ≤ Ai ≤ 100000,1 ≤ Ci ≤ 1000). The last test case is followed by two zeros.

    Output

    For each test case output the answer on a single line.

    Sample Input

    3 10
    1 2 4 2 1 1
    2 5
    1 4 2 1
    0 0

    Sample Output

    8
    4

    Source

    超时代码:
     1 /*可以看出直接枚举物品件数和二进制拆分后01背包都不是很快,最快的方法是在DP里面用二进制拆分最快*/
     2 /*------------------------超时代码---------------------------------------------*/
     3 #define N 100010
     4 #include<iostream>
     5 using namespace std;
     6 #include<cstdio>
     7 #include<cstring>
     8 #include<vector>
     9 int n,m,a[101],c[101];
    10 bool f[N];
    11 int main()
    12 {
    13     /*vector<int>wu;
    14     while(scanf("%d%d",&n,&m)==2)
    15     {
    16         if(n==0&&m==0) break;
    17         memset(f,false,sizeof(f));
    18         clac=0;
    19         memset(a,0,sizeof(a));
    20         memset(c,0,sizeof(c));
    21         f[0]=true;
    22         wu.clear();
    23         for(int i=1;i<=n;++i)
    24             scanf("%d",&a[i]);
    25         for(int i=1;i<=n;++i)
    26             scanf("%d",&c[i]);
    27         for(int i=1;i<=n;++i)
    28         {
    29             for(int ki=1;ki<=c[i];ki<=1)
    30             {
    31                 clac++;
    32                 wu.push_back(ki*a[i]);
    33                 c[i]-=ki;
    34             }
    35             if(c[i])
    36             {
    37                 clac++;
    38                 wu.push_back(c[i]*a[i]);
    39                 c[i]=0;
    40             }
    41         }
    42         for(int i=0;i<clac;++i)
    43           for(int j=m;j>=wu[i];--j)
    44           f[j]=f[j]||f[j-wu[i]];
    45         int ret=0;
    46         for(int i=1;i<=m;++i)
    47           if(f[i]) ret++;
    48         printf("%d
    ",ret);
    49     }*/
    50     while(scanf("%d%d",&n,&m)==2)
    51     {
    52         if(n==0&&m==0) break;
    53         memset(f,false,sizeof(f));
    54         f[0]=true;
    55         for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    56         for(int i=1;i<=n;++i) scanf("%d",&c[i]);
    57         for(int i=1;i<=n;++i)
    58           for(int j=1;j<=c[i];++j)
    59              for(int k=m;k>=1;--k)
    60               if(k>=a[i]) f[k]=f[k]||f[k-a[i]];
    61         int ret=0;
    62         for(int i=1;i<=m;++i)
    63           if(f[i])ret++;
    64         printf("%d
    ",ret);
    65     }
    66     return 0;
    67 }
     1 /*不知道为什么这个也一直超时*/
     2 #define N 100010
     3 #include<iostream>
     4 using namespace std;
     5 #include<cstring>
     6 #include<cstdio>
     7 int n,m,a[101],c[101];
     8 int f[N];
     9 int main()
    10 {
    11     while(scanf("%d%d",&n,&m)==2)
    12     {
    13         if(n==0&&m==0) break;
    14         memset(f,0,sizeof(f));
    15         f[0]=1;
    16         for(int i=1;i<=n;++i)
    17             scanf("%d",&a[i]);
    18         for(int i=1;i<=n;++i)
    19             scanf("%d",&c[i]);
    20         for(int i=1;i<=n;++i)
    21         {
    22             for(int ki=1;ki<=c[i];ki<=1)
    23             {
    24                 for(int j=m;j>=ki*a[i];--j)/*相当于更新过程了*/
    25                   f[j]+=f[j-ki*a[i]];
    26                 c[i]-=ki;
    27             }
    28             if(c[i])
    29             {
    30                 for(int j=m;j>=c[i]*a[i];--j)
    31                   f[j]+=f[j-a[i]*c[i]];
    32             }
    33         }
    34         int ret=0;
    35         for(int i=1;i<=m;++i)
    36           if(f[i]) ret++;
    37         printf("%d
    ",ret);
    38     }
    39     return 0;
    40 }
     1 /*网上的AC代码*/
     2 #include<iostream>  
     3 #include<cstdio>
     4 #include<cstring>
     5 using namespace std;  
     6 int f[100005];  
     7 int p[105],c[105];  
     8 int main()  
     9 {  
    10     int i,j,k,n,m,cnt;  
    11     while(scanf("%d%d",&n,&m)!=EOF)  
    12     {  
    13       if(n==0&&m==0) break;  
    14       for(i=0;i<n;i++)  
    15         scanf("%d",&p[i]);  
    16       for(i=0;i<n;i++)  
    17         scanf("%d",&c[i]);  
    18       memset(f,0,sizeof(f));  
    19       f[0]=1;  
    20       for(i=0;i<n;i++)  
    21       {  
    22         cnt=c[i];  
    23         for(k=1;k<=cnt;k<<=1)  
    24         {  
    25           for(j=m;j>=k*p[i];j--)  
    26              f[j]+=f[j-k*p[i]];  
    27           cnt-=k;  
    28         }  
    29         if(cnt)  
    30           for(j=m;j>=cnt*p[i];j--) f[j]+=f[j-cnt*p[i]];  
    31       }  
    32       int sum=0;  
    33       for(i=1;i<=m;i++)  
    34         if(f[i]) sum++;  
    35       printf("%d
    ",sum);  
    36  }  
    37  return 0;  
    38 }  
  • 相关阅读:
    新收入准则下的通用收入处理场景
    如果不先提出最佳问题,你怎么去找最佳答案呢?
    复星集团
    CFO的三重境界:阿里CFO蔡崇信教给我的那些事儿
    《让财务助推业务—业财融合》
    一、原材料、半成品、成品的采用标准成本法管理 [转发]
    顶级投行?IT->Data Analysis->Forecast->Future.
    SAP 合资公司解决方案
    SAP-关于分类账(Ledgers)的总结
    百度网盘目录树在线V2.0版功能介绍~
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5990670.html
Copyright © 2011-2022 走看看