简单的背包问题(入门)HDU2602 HDU2546 HDU1864
来源:互联网 发布:淘宝怎么绕过实拍保护 编辑:程序博客网 时间:2024/05/24 04:26
动态规划,我一直都不熟悉,因为体量不够,所以今天开始努力地学习学习。
当然背包从01开始,先选择了一个简单的经典的背包HDU2602。
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 ?
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.
One integer per line representing the maximum of the total value (this number will be less than 231).
Input
15 101 2 3 4 55 4 3 2 1Output
14C++代码
/*******************************************************************************//* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux * Compiler : g++ (GCC) 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) * Encoding : UTF8 * Date : 2014-03-08 * All Rights Reserved by yaolong.*****************************************************************************//* Description: ********************************************************************************************************************************************//* Analysis: ***********************************************************************************************************************************************//*****************************************************************************/#include <iostream>#include <cstring>int max(int a,int b){ return a>b?a:b;}using namespace std;int dp[1003];int v[1003];int w[1003];int main(){ int cases,i,j,val,n; cin>>cases; while(cases--){ memset(dp,0,sizeof(dp)); memset(v,0,sizeof(v)); memset(w,0,sizeof(w)); cin>>n>>val; for(i=1;i<=n;i++){ cin>>w[i]; } for(i=1;i<=n;i++){ cin>>v[i]; } for(i=1;i<=n;i++) for(j=val;j>=v[i];j--) dp[j]=max(dp[j],dp[j-v[i]]+w[i]); cout<<dp[val]<<endl; } return 0;}
后来特意选了一道HDU的简单背包问题。HDU的2546。
题目很简单:
电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无法购买(即使金额足够)。所以大家都希望尽量使卡上的余额最少。
某天,食堂中有n种菜出售,每种菜可购买一次。已知每种菜的价格以及卡上的余额,问最少可使卡上的余额为多少。
多组数据。对于每组数据:
第一行为正整数n,表示菜的数量。n<=1000。
第二行包括n个正整数,表示每种菜的价格。价格不超过50。
第三行包括一个正整数m,表示卡上的余额。m<=1000。
n=0表示数据结束。
对于每组输入,输出一行,包含一个整数,表示卡上可能的最小余额。
其实这道题在01背包上多了一个弯,就是卡余额大于等于5可以购买任何东西。只要留下5元买最贵的东西,剩下的就是一个背包问题了。
/*******************************************************************************//* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux * Compiler : g++ (GCC) 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) * Encoding : UTF8 * Date : 2014-03-08 * All Rights Reserved by yaolong. *****************************************************************************//* Description: *************************************************************** *****************************************************************************//* Analysis: ****************************************************************** *****************************************************************************//*****************************************************************************///*#include <iostream>#include <cstring>using namespace std;int min(int a,int b){ return a>b?b:a;}int main(){ int n,i,j,V; int c[1002]; int f[1002]; while(cin>>n&&n){ int max=0,mi=0; for(i=1;i<=n;i++){ cin>>c[i]; //cout<<c[i]; if(c[i]>max){ max=c[i]; mi=i; } } cin>>V; if(V<5){ cout<<V<<endl; }else{ for(j=0;j<=V;j++) f[j]=V; V-=5; for(i=1;i<=n;i++) if(i!=mi) for(j=V;j>=c[i];j--){ f[j]=min(f[j],f[j-c[i] ]-c[i]); } cout<<f[V]-c[mi]<<endl; } } return 0;}
对于HDU1864这题目,则是明显的01背包,但是其中要做一些小小的处理。
我的方法很一般,而且效率也不怎么高,就算是很传统吧。如果用C语言写的话会略去一些没必要的字符串处理过程。
因为题目是两位小数的,所以我很暴力地全部*100,空间浪费了很多,但是500000的空间能过。
现有一笔经费可以报销一定额度的发票。允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元。现请你编写程序,在给出的一堆发票中找出可以报销的、不超过给定额度的最大报销额。
测试输入包含若干测试用例。每个测试用例的第1行包含两个正数 Q 和 N,其中 Q 是给定的报销额度,N(<=30)是发票张数。随后是 N 行输入,每行的格式为:
m Type_1:price_1 Type_2:price_2 ... Type_m:price_m
其中正整数 m 是这张发票上所开物品的件数,Type_i 和 price_i 是第 i 项物品的种类和价值。物品种类用一个大写英文字母表示。当N为0时,全部输入结束,相应的结果不要输出。
代码:
/*******************************************************************************//* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux * Compiler : g++ (GCC) 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) * Encoding : UTF8 * Date : 2014-03-08 * All Rights Reserved by yaolong. *****************************************************************************//* Description: *************************************************************** *****************************************************************************//* Analysis: ****************************************************************** *****************************************************************************//*****************************************************************************///*#include <iostream>#include <string>#include <cstdlib>#include <cstring>#include <cstdio>#include <iomanip>using namespace std;int max(int a,int b){ return a>b?a:b;}int f[5000000];int main(){ float money; int n,m,i,j; string tmp; float c[32]; //float f[32]; int ci[32]; int moneyi; // freopen("input.txt","r",stdin); while(cin>>money>>n&&n){ memset(f,0,sizeof(f)); memset(c,0.0f,sizeof(c)); for(i=1;i<=n;i++){ cin>>m; int flag=1; float A,B,C; A=B=C=0.0f; while(m--){ cin>>tmp; float a; if(tmp[0]=='A'){ tmp.erase(0,1); tmp.erase(0,1); a=atof(tmp.c_str()); A+=a; }else if(tmp[0]=='C'){ tmp.erase(0,1); tmp.erase(0,1); a=atof(tmp.c_str()); C+=a; }else if(tmp[0]=='B'){ tmp.erase(0,1); tmp.erase(0,1); a=atof(tmp.c_str()); B+=a; }else{ flag=0; } } if(flag&&A+B+C<=1000.0f&&A<=600.0F&&B<=600.0F&&C<=600.0f){ c[i]=A+B+C; }else{ c[i]=0; } //cout // cout<<c[i]<<endl; } for(i=1;i<=n;i++){ //cout<<100*c[i]; ci[i]=(int)(100*c[i]); // cout<<"ci[i]"<<ci[i]<<endl; } moneyi=(int)(money*100); //cout<<"m="<<moneyi<<endl; for(i=1;i<=n;i++) for(j=moneyi;j>=ci[i];j--){ f[j]=max(f[j],f[j-ci[i]]+ci[i]); } double xs=f[moneyi]/100.0; cout<<setprecision(2) <<std::fixed<<xs<<endl; } // fclose(stdin); //关闭文件 return 0;}
C代码:
/*******************************************************************************//* OS : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux * Compiler : GCC 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) * Encoding : UTF8 * Date : 2014-03-08 * All Rights Reserved by yaolong.*****************************************************************************//* Description: ********************************************************************************************************************************************//* Analysis: ***********************************************************************************************************************************************//*****************************************************************************/#include <stdio.h>#include <string.h>int main(){ double money,A,B,C,tmp; int n,m,i,j,flag; char c; double dp[32]; double w[32]; while(scanf("%lf%d",&money,&n)!=EOF&&n){ memset(w,0,sizeof(w)); memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++){ scanf("%d",&m); A=B=C=0; flag=1; for(j=1;j<=m;j++){ scanf(" %c:%lf",&c,&tmp); if(c=='A'){ A+=tmp; }else if(c=='B'){ B+=tmp; }else if(c=='C'){ C+=tmp; }else{ flag=0; } } if(flag&&A<=600.0&&B<=600.0&&C<=600.0&&A+B+C<=1000.0){ w[i]=A+B+C; }else{ w[i]=0.0; } } for(i=1;i<=n;i++) for(j=n;j>=1;j--) if(money-w[j]>=dp[j-1]||j==1) dp[j]=(dp[j]>dp[j-1]+w[i])?dp[j]:dp[j-1]+w[i]; double res=0; for(i=1;i<=n;i++){ if(res<=dp[i]) res=dp[i]; } printf("%.2lf\n",res); } return 0;}
- 简单的背包问题(入门)HDU2602 HDU2546 HDU1864
- HDU2602(简单背包问题)
- 01背包 hdu2546 hdu2602
- hdu1864(简单的01背包)
- (简单01背包)HDU2602
- HDU2602 Bone Collector (简单01背包问题)
- hdu2602 Bone Collector_简单的01背包
- hdu2602 Bone Collector(01背包+入门)
- hdu2602 简单01背包
- 饭卡 hdu2546 背包问题
- hdu2546 饭卡 (背包问题)
- hdu2602 Bone Collector(背包问题)
- HDU2602—Bone Collector(背包问题)
- hdu2602 Bone Collector(01背包问题)
- hdu2602!01背包问题
- hdu2602 01背包问题
- HDU2602 01背包问题
- hdu1864 (01背包)
- 基于HEVC的码率控制的相关提案的文献综述
- JSP中动态INCLUDE与静态INCLUDE的区别?
- 指出下面程序的运行结果:
- 写一个Singleton模式的例子
- ASP.NET 状态的传递和保持
- 简单的背包问题(入门)HDU2602 HDU2546 HDU1864
- PATA 1073. Scientific Notation (20)
- J2EE是什么?
- java线程管理利器:java.util.current的用法举例
- QT模态对话框及非模态对话框学习
- 点滴的学习快乐——CorelDraw 学习笔记 (1)
- 体会插入迭代器
- Thinking in BigDate(七)大数据技术核心之NoSql(一)
- hdu-4524- 郑厂长系列故事——逃离迷宫