HDU 2191多重背包问题、

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<cstring> 
 5 const int qq=2000+50;
 6 int v[qq],w[qq],dp[qq];
 7 using namespace std;
 8 int main()
 9 {
10     int t;
11     scanf("%d",&t);
12     while(t--){
13         int n,m;
14         scanf("%d %d",&n,&m);
15         memset(dp,0,sizeof(dp));
16         memset(v,0,sizeof(v));
17         memset(w,0,sizeof(w));
18         int count=1;
19         for(int i=0;i<m;++i){
20             int value,weight,tot;
21             scanf("%d %d %d",&value,&weight,&tot);
22             int t=1;
23             while(tot>=t){
24                 v[count]=t*value;
25                 w[count++]=t*weight;
26                 tot-=t;
27                 t<<=1;
28             }
29             if(tot){
30                 v[count]=tot*value;
31                 w[count++]=tot*weight;
32             }
33         }
34         for(int i=1;i<count;++i)
35             for(int j=n;j>=v[i];--j)        //j必须从n开始dp,如果循序开始dp的话v[i]会被取多次 
36                 dp[j]=max(dp[j],dp[j-v[i]]+w[i]);     //也就是说达不到01背包要求的v[i]只有取和不取两种状态、 
37             printf("%d
",dp[n]); 
38     }
39 }

 算法时间复杂度O(V*∑log n[i])

总算是理解了为什么要逆序dp

#include <stdio.h>  
02.#include <string.h>  
03.#include <algorithm>  
04.using namespace std;  
05.int main()  
06.{  
07.    int ncase,p[105],w[105],c[105],dp[105];  
08.    scanf("%d",&ncase);  
09.    while(ncase--)  
10.    {  
11.        int n,m,count=0;  
12.        scanf("%d %d",&n,&m);  
13.        for(int i=0;i<m;i++)  
14.        scanf("%d %d %d",&p[i],&w[i],&c[i]);  
15.        memset(dp,0,sizeof(dp));  
16.        int temp=0;  
17.        for(int i=0;i<m;i++)  
18.        {  
19.            for(int j=n;j>=p[i];j--)//唉在这里又错了几次 要倒着来。  
20.            {  
21.                for(int k=1;k<=c[i];k++)  
22.                {  
23.                    if(j<k*p[i]) break;  
24.                    dp[j]=max(dp[j-k*p[i]]+k*w[i],dp[j]);  
25.                    if(dp[j]>temp)  
26.                    temp=dp[j];  
27.                }  
28.            }  
29.        }  
30.        printf("%d
",temp);  
31.    }  
32.    return 0;  
33.}  

上述代码是借鉴别人的、   也是多重背包最原始的解法

时间复杂度O(V*∑n[i])

原文地址:https://www.cnblogs.com/sasuke-/p/5240139.html