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\n",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\n",temp);
31.    }
32.    return 0;
33.}  

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

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

时间: 2024-10-08 06:25:34

HDU 2191多重背包问题、的相关文章

hdu 2191多重背包

悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 22553    Accepted Submission(s): 9524 Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市

hdu 2191 多重背包 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

http://acm.hdu.edu.cn/showproblem.php?pid=2191 New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院关于2015年杭电ACM暑期集训队的选拔 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17930    Accepted

HDU 2191 多重背包

悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 22865    Accepted Submission(s): 9661 Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市

hdu 2191 多重背包,自己写模板

背景:wa了几次,都是小失误:把i--写成i++之类的,写的时候一定要想到具体用意.还有就是一定要至少写三组测试数据!!!!!!! 学习:模板化写多重背包. #include<cstdio> #include<iostream> #include<cstring> using namespace std; int t,v,n; int c[109],w[109],num[109],F[109]; void zeroonebag(int cost,int weight){

HDU 1059 多重背包问题

问题大意: 有价值1-6的六种物品,分别规定其数目,问是否存在一种方法能使这些物品不拆分就能平均分给两个人 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 6 int v[7] , ans , k; 7 int dp[500000]; 8 //0-1背包 9 void zeroPack(int w , int v) 10 { 11 for(in

hdu 2191 (多重背包的单调队列优化)

多重背包单调队列优化是思想是.普通的dp为 dp[i][j]=max{dp[i-1][j-k*v[i]]+k*w[i]}; 其实你可以发现对能更新j是j和一个剩余类.也就是 0, v[i],2v[i],3v[i] ,4v[i]... 1 ,1+v[i],1+2v[i],1+3v[i] ........... v[i]-1,2*v[i]-1...... 更新值存在一个剩余类中,组与组之间不存在更新.那么实际上我们可以写dp写好这样 dp[b+x*v[i]]=max{ dp[b+k*v[i]]+(x

HDU ACM 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活-&gt;多重背包问题

分析:多重背包问题.这里直接转换为01背包,为使用二进制. #include<iostream> using namespace std; int price[101]; int weight[101]; int number[101]; int dp[101]; int main() { int C,n,m; int i,j,k; cin>>C; while(C--) { cin>>n>>m; for(i=0;i<m;i++) { cin>&g

HDU #2191 买米问题 多重背包及其优化

Description 问题描述以及测试样例在这:HDU#2191 思路 这道题其实就是多重背包问题,即有 N 种物品和一个容量为 V 的背包,第 i 种物品最多有 n[i] 件可用,每件费用是 c[i] ,价值是 w[i] ,求哪些物品装入背包可以使得这些物品的费用总和不超过背包容量,且价值总和最大.在这道题中,背包容量是经费,费用是每种米的价格,价值是每种米的重量,求用给定的经费买米,使得买到米的总重量最大,注意经费是可以剩余的. 其实多重背包问题和完全背包问题非常相似,只不过前者的物品是有

[ACM] hdu 2191 珍惜如今,感恩生活 (多重背包)

Problem Description 急!灾区的食物依旧短缺! 为了拯救灾区同胞的生命,心系灾区同胞的你准备自己採购一些粮食支援灾区,如今如果你一共同拥有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,而且仅仅能整袋购买. 请问:你用有限的资金最多能採购多少公斤粮食呢? 后记: 人生是一个充满了变数的生命过程,天灾.人祸.病痛是我们生命历程中不可预知的威胁. 月有阴晴圆缺,人有旦夕祸福,未来对于我们而言是一个未知数.那么,我们要做的就应该是珍惜如今,感恩生活-- 感谢父母,他们给