hdu - 动态规划 入门小结 - Bone Collector - 2191 - 重温世界杯 1422
2014-12-07 21:28
393 查看
一: 01背包简单题 Bone Collector
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 32299 Accepted Submission(s): 13289
Problem Description
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the
maximum of the total value the bone collector can get ?
Input
The first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third
line contain N integers representing the volume of each bone.
Output
One integer per line representing the maximum of the total value (this number will be less than 231).
Sample Input
Sample Output
01背包就是对于每件物品拿或不拿。
for i..n 对于每件物品的循环
for tol..vol[ i ] 以容量为下标dp内存的是价值
if( 拿起第i件的价值 比 不拿起第i件的价值 大)
更新dp[ j ]
二:多重背包 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 15716 Accepted Submission(s): 6656
Problem Description
急!灾区的食物依然短缺!
为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买。
请问:你用有限的资金最多能采购多少公斤粮食呢?
后记:
人生是一个充满了变数的生命过程,天灾、人祸、病痛是我们生命历程中不可预知的威胁。
月有阴晴圆缺,人有旦夕祸福,未来对于我们而言是一个未知数。那么,我们要做的就应该是珍惜现在,感恩生活——
感谢父母,他们给予我们生命,抚养我们成人;
感谢老师,他们授给我们知识,教我们做人
感谢朋友,他们让我们感受到世界的温暖;
感谢对手,他们令我们不断进取、努力。
同样,我们也要感谢痛苦与艰辛带给我们的财富~
Input
输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。
Output
对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。
Sample Input
Sample Output
多重背包,对于每种物品都有一定的数量。
最简单粗暴的方式,就是将多重背包直接用一个循环 for ( 此种物品的数量 )转化为0 1 背包。
输入的时候直接转化为0 1 背包:
dp的时候多加一个循环也ok 的:
三:子序列和变形题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4781 Accepted Submission(s): 1642
Problem Description
世界杯结束了,意大利人连本带利的收回了法国人6年前欠他们的债,捧起了大力神杯,成就了4星意大利.
世界杯虽然结束了,但是这界世界杯给我们还是留下许多值得回忆的东西.比如我们听到了黄名嘴的3分钟激情解说,我们懂得了原来可以向同一个人出示3张黄牌,我们还看到了齐达内的头不仅能顶球还能顶人…………
介于有这么多的精彩,xhd决定重温德国世界杯,当然只是去各个承办世界杯比赛的城市走走看看.但是这需要一大比钱,幸运的是xhd对世界杯的热爱之情打动了德国世界杯组委会,他们将提供xhd在中国杭州和德国任意世界杯承办城市的往返机票,并说服了这些城市在xhd到达这座城市时为他提供一笔生活费以便他在那里参观时用,当参观完时剩余的钱也将留给xhd,但当生活费不够时他们将强行结束xhd的这次德国之行,除了这个,他们还有一个条件,xhd只能根据他们所给的路线参观.比如有3座城市a,b,c,他们给定了a-b-c-a的路线,那么xhd只有3种参观顺序abc,bca,cab.由于各个城市所提供的生活费和在那里的花费都不同,这使xhd很头痛,还好我们事先知道了这笔生活费和花费.请问xhd最多能顺利参观几座城市?
Input
每组输入数据分两行,第一行是一个正整数n(1<=n<=100000),表示有n座城市.接下来的一行按照给定的路线顺序的输出这n个城市的生活费和花费,w1,l1,w2,l2,……,wn,ln,其中wi,li分别表示第i个城市的生活费和花费,并且它们都是正整数.
Output
对应每组数据输出最多能参观的城市数.
Sample Input
Sample Output
输入的时候每次的生活费减去花费,就是每个城市剩余的钱。
注意这是一个环形子序列问题就好了,每次累积的剩余的钱要>=0
Bone Collector
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 32299 Accepted Submission(s): 13289
Problem Description
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the
maximum of the total value the bone collector can get ?
Input
The first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third
line contain N integers representing the volume of each bone.
Output
One integer per line representing the maximum of the total value (this number will be less than 231).
Sample Input
1 5 10 1 2 3 4 5 5 4 3 2 1
Sample Output
14
01背包就是对于每件物品拿或不拿。
for i..n 对于每件物品的循环
for tol..vol[ i ] 以容量为下标dp内存的是价值
if( 拿起第i件的价值 比 不拿起第i件的价值 大)
更新dp[ j ]
#include<iostream> #include<cstdio> #include<cstring> const int MX = 1000+5; using namespace std; int value[MX],vol[MX]; int dp[MX]; int tol,cas,num; #define FOR(i,n) for( int i = 0;i<n;++i) void DP() { FOR(i,num) { for( int j = tol; j >=vol[i];--j) if( dp[j]<dp[j-vol[i] ] + value[i]) dp[j]= dp[j-vol[i] ] + value[i]; } } int main() { cin>>cas; while(cas--) { cin>>num>>tol; FOR(i,num) scanf("%d",&value[i] ); FOR(i,num) scanf("%d",&vol[i]); memset(dp,0,sizeof(dp)); DP(); cout<<dp[tol]<<endl; } return 0; }
二:多重背包 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 15716 Accepted Submission(s): 6656
Problem Description
急!灾区的食物依然短缺!
为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买。
请问:你用有限的资金最多能采购多少公斤粮食呢?
后记:
人生是一个充满了变数的生命过程,天灾、人祸、病痛是我们生命历程中不可预知的威胁。
月有阴晴圆缺,人有旦夕祸福,未来对于我们而言是一个未知数。那么,我们要做的就应该是珍惜现在,感恩生活——
感谢父母,他们给予我们生命,抚养我们成人;
感谢老师,他们授给我们知识,教我们做人
感谢朋友,他们让我们感受到世界的温暖;
感谢对手,他们令我们不断进取、努力。
同样,我们也要感谢痛苦与艰辛带给我们的财富~
Input
输入数据首先包含一个正整数C,表示有C组测试用例,每组测试用例的第一行是两个整数n和m(1<=n<=100, 1<=m<=100),分别表示经费的金额和大米的种类,然后是m行数据,每行包含3个数p,h和c(1<=p<=20,1<=h<=200,1<=c<=20),分别表示每袋的价格、每袋的重量以及对应种类大米的袋数。
Output
对于每组测试数据,请输出能够购买大米的最多重量,你可以假设经费买不光所有的大米,并且经费你可以不用完。每个实例的输出占一行。
Sample Input
1 8 2 2 100 4 4 100 2
Sample Output
400
多重背包,对于每种物品都有一定的数量。
最简单粗暴的方式,就是将多重背包直接用一个循环 for ( 此种物品的数量 )转化为0 1 背包。
输入的时候直接转化为0 1 背包:
#include<iostream> #include<cstring> #include<cmath> using namespace std; const int MX =4000; int dp[MX]; int price[MX],wei[MX],num[MX]; void DP(int n,int id) { for( int i = 1; i <=id;++i) { for(int j =n;j>=price[i];--j ) { dp[j] = max( dp[j],dp[j-price[i]]+wei[i] ); } } } int main() { int cas; cin>>cas; while( cas-- ) { int n,m; int id = 0; int a,b,c; cin>>n>>m; for( int i = 1; i <=m;++i) { cin>>a>>b>>c; while(c--) { price[++id] = a; wei[id] = b; } } memset(dp,0,sizeof(dp)); DP(n,id); cout<< dp <<endl; } return 0; }
dp的时候多加一个循环也ok 的:
#include<iostream> #include<cstring> #include<cmath> using namespace std; const int MX =4000; int dp[MX]; int price[MX],wei[MX],num[MX]; void DP(int n,int m) { for( int i = 1; i <=m;++i) { for( int k = 1; k <=num[i];++k) for(int j =n;j>=price[i];--j ) { dp[j] = max( dp[j],dp[j-price[i]]+wei[i] ); } } } int main() { int cas; cin>>cas; while( cas-- ) { int n,m; //int id = 0; int a,b,c; cin>>n>>m; for( int i = 1; i <=m;++i) { cin>>price[i]>>wei[i]>>num[i]; } memset(dp,0,sizeof(dp)); DP(n,m); cout<< dp <<endl; } return 0; }
三:子序列和变形题
重温世界杯
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4781 Accepted Submission(s): 1642
Problem Description
世界杯结束了,意大利人连本带利的收回了法国人6年前欠他们的债,捧起了大力神杯,成就了4星意大利.
世界杯虽然结束了,但是这界世界杯给我们还是留下许多值得回忆的东西.比如我们听到了黄名嘴的3分钟激情解说,我们懂得了原来可以向同一个人出示3张黄牌,我们还看到了齐达内的头不仅能顶球还能顶人…………
介于有这么多的精彩,xhd决定重温德国世界杯,当然只是去各个承办世界杯比赛的城市走走看看.但是这需要一大比钱,幸运的是xhd对世界杯的热爱之情打动了德国世界杯组委会,他们将提供xhd在中国杭州和德国任意世界杯承办城市的往返机票,并说服了这些城市在xhd到达这座城市时为他提供一笔生活费以便他在那里参观时用,当参观完时剩余的钱也将留给xhd,但当生活费不够时他们将强行结束xhd的这次德国之行,除了这个,他们还有一个条件,xhd只能根据他们所给的路线参观.比如有3座城市a,b,c,他们给定了a-b-c-a的路线,那么xhd只有3种参观顺序abc,bca,cab.由于各个城市所提供的生活费和在那里的花费都不同,这使xhd很头痛,还好我们事先知道了这笔生活费和花费.请问xhd最多能顺利参观几座城市?
Input
每组输入数据分两行,第一行是一个正整数n(1<=n<=100000),表示有n座城市.接下来的一行按照给定的路线顺序的输出这n个城市的生活费和花费,w1,l1,w2,l2,……,wn,ln,其中wi,li分别表示第i个城市的生活费和花费,并且它们都是正整数.
Output
对应每组数据输出最多能参观的城市数.
Sample Input
3 3 2 3 4 2 2 3 3 2 3 4 2 3
Sample Output
3 2
输入的时候每次的生活费减去花费,就是每个城市剩余的钱。
注意这是一个环形子序列问题就好了,每次累积的剩余的钱要>=0
#include<iostream> #include<cstdio> const int MX = 100000+5; int dp[MX]; int sum,mav,n; using namespace std; #define FONE(i,n) for(int i = 1;i <=n;++i) #define FOR(i,n) for( int i =0;i<n;++i) #define MV(a,b) (a)>(b)?(a):(b) int work() { int m = 2*n-1; int cnr = 0; mav = 0; sum = 0; FOR(i,m) { sum+=dp[i%n]; if( sum >= 0) { cnr++; mav =MV(cnr,mav); if( cnr==n)break; } else { cnr = 0 ; sum = 0; } } return mav; } int main() { while( cin>>n ) { int a,b; FOR(i,n) { scanf("%d %d",&a,&b); dp[i] = a-b; } dp = 0; int ans = work(); cout<<ans<<endl; } return 0; }
相关文章推荐
- hdu 1422 重温世界杯(动态规划)
- hdu 1422 重温世界杯 dp
- hdu 1422 重温世界杯(最大连续子段和变形)
- HDU 1422 重温世界杯 DP题
- HDU 1422 重温世界杯(DP)
- HDOJ 1422 重温世界杯 -- 动态规划
- HDU 1422 重温世界杯 解题报告
- [HDU 1422]重温世界杯(DP)
- HDU-1422 重温世界杯 ACM解题报告(贪心)
- 【DP|水】HDU-1422 重温世界杯
- HDU 1422 重温世界杯
- hdu1422 重温世界杯(dp)
- hdu 1422【重温世界杯】
- 【瞎搞】HDU 1422 重温世界杯
- Hdu1422 重温世界杯(模拟)
- hdu 1422 重温世界杯(DP 最长非负子序列)
- HDU 1422 重温世界杯【最长非负连续子序列】
- hdoj problem 1422 重温世界杯(动态规划)
- hdu 1422 重温世界杯
- hdu 1422 重温世界杯 类似最大子串和