zoukankan      html  css  js  c++  java
  • 动态规划[入门3]-多重背包问题

    分析:这个和我们之前讲的0-1背包问题很像。

    思路1:
    我们显然可以把每种物品的每一件都作为一个新的物品按照普通0-1背包的方法做。
    但是0-1背包的时间复杂度是O(W * N) , 这里N = C1 + C2 + …+ Cn。

    思路2:
    换个角度我们用dp[i][j]表示前i件物品,总重量为j的时候的最大价值。
    则dp[i][j] = max{dp[i – 1][j – k * Wi] + k * Vi}
    其中 0 ≤ k ≤ min( j / Wi , Ci)

    这个的时间复杂度是n * W * max(Ci)
    最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。
     
    输入

    第1行,2个整数,N和W中间用空格隔开。N为物品的种类,W为背包的容量。(1 <= N <= 100,1 <= W <= 50000)
    第2 - N + 1行,每行3个整数,Wi,Pi和Ci分别是物品体积、价值和数量。(1 <= Wi, Pi <= 10000, 1 <= Ci <= 200)
    输出
     
    输出可以容纳的最大价值。
     
    输入示例

    3 6
    2 2 5
    3 3 8
    1 4 1

    输出示例

    9
     
    请选取你熟悉的语言,并在下面的代码框中完成你的程序,注意数据范围,最终结果会造成Int32溢出,这样会输出错误的答案。
     1 line=input().split()
     2 n=int(line[0])
     3 m=int(line[1])
     4 w=[]
     5 p=[]
     6 c=[]
     7 for i in range(n):
     8     line=input().split()
     9     tw=int(line[0])
    10     tp=int(line[1])
    11     tc=int(line[2])
    12     k=1
    13     while tc>=k:
    14         w.append(k*tw)
    15         p.append(k*tp)
    16         tc-=k
    17         k*=2
    18     if tc>0:    
    19         w.append(tc*tw)
    20         p.append(tc*tp)
    21 n2=len(w)
    22 f=[]
    23 for i in range(m+1):
    24     f.append(0)
    25 for i in range(n2):
    26     for j in range(m,w[i]-1,-1):
    27         f[j]=max(f[j],f[j-w[i]]+p[i])
    28 print(f[m])        
    29     

    又超时!!

     1 #include<cstdio>
     2 int max(int a,int b){
     3     if (a>b) return a;
     4     else return b;
     5 }
     6 int main(){
     7     int n,m,c,tw,tp;
     8     int w[1000],p[1000],f[50000];
     9     scanf("%d%d",&n,&m);
    10     int j=-1;
    11     for(int i=0;i<n;i++){
    12         scanf("%d%d%d",&tw,&tp,&c);    
    13         int k=1;
    14         while (c>=k){
    15             j++;
    16             w[j]=tw*k;
    17             p[j]=tp*k;
    18             c-=k;
    19             k*=2;
    20         }
    21         if (c>0){
    22             j++;
    23             w[j]=tw*c;
    24             p[j]=tp*c;
    25         }
    26     }
    27     int n2=j+1;
    28     for(int i=0;i<=m;i++){
    29         f[i]=0;
    30     }
    31     for(int i=0;i<n2;i++){
    32         for(int j=m;j>=w[i];j--){
    33             f[j]=max(f[j],f[j-w[i]]+p[i]);
    34         }
    35     }
    36     printf("%ld",f[m]);
    37     return 0;
    38 }
  • 相关阅读:
    linux ubuntu装机到可实现java(eclipse,intellij IDEA,android)开发全过程
    浅谈线程同步的几种方法
    KMP算法,这是我看到的最简单的最好理解的KMP算法
    常用基础算法C++实现
    堆内存和栈内存详解(转载)
    数据结构=。= 链表
    倒排索引--资料1
    倒排索引简单理解
    简单理解Socket
    8.结构体的使用 2015.12.3
  • 原文地址:https://www.cnblogs.com/nbalive2001/p/4870950.html
Copyright © 2011-2022 走看看