HDOJ-1864 最大报销额[DP-01背包问题]
转自:http://blog.csdn.net/kay_sprint/article/details/7237608#cpp
最大报销额
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10318 Accepted Submission(s): 2769
Problem Description
现有一笔经费可以报销一定额度的发票。允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元。现请你编写程序,在给出的一堆发票中找出可以报销的、不超过给定额度的最大报销额。
Input
测试输入包含若干测试用例。每个测试用例的第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时,全部输入结束,相应的结果不要输出。
m Type_1:price_1 Type_2:price_2 ... Type_m:price_m
其中正整数 m 是这张发票上所开物品的件数,Type_i 和 price_i 是第 i 项物品的种类和价值。物品种类用一个大写英文字母表示。当N为0时,全部输入结束,相应的结果不要输出。
Output
对每个测试用例输出1行,即可以报销的最大数额,精确到小数点后2位。
Sample Input
200.00 3 2 A:23.50 B:100.00 1 C:650.00 3 A:59.99 A:120.00 X:10.00 1200.00 2 2 B:600.00 A:400.00 1 C:200.50 1200.50 3 2 B:600.00 A:400.00 1 C:200.50 1 A:100.00 100.00 0
Sample Output
123.50 1000.00 1200.50
Source
Recommend
lcy
汗死,以后开打数组不要在main函数里面,会暴栈的!
code:
1 #include <iostream> 2 #include <iomanip> 3 #include <fstream> 4 #include <sstream> 5 #include <algorithm> 6 #include <string> 7 #include <set> 8 #include <utility> 9 #include <queue> 10 #include <stack> 11 #include <list> 12 #include <vector> 13 #include <cstdio> 14 #include <cstdlib> 15 #include <cstring> 16 #include <cmath> 17 #include <ctime> 18 #include <ctype.h> 19 using namespace std; 20 21 int dp[3000100]; 22 int invoice[102]; 23 24 int main() 25 { 26 int i,j; 27 int n,m; 28 double q; 29 double a,b,c; 30 char ch; 31 double temp; 32 bool flag; 33 int cnt; 34 while(~scanf("%lf%d",&q,&n),n) 35 { 36 cnt=0; 37 while(n--) 38 { 39 a=b=c=0; 40 flag=true; 41 scanf("%d ",&m); 42 for(i=0;i<m;i++) 43 { 44 scanf(" %c:%lf",&ch,&temp); 45 if(ch=='A') 46 a+=temp; 47 else if(ch=='B') 48 b+=temp; 49 else if(ch=='C') 50 c+=temp; 51 else 52 { 53 flag=false; 54 break; 55 } 56 } 57 if(flag&&(a<=600&&b<=600&&c<=600&&a+b+c<=1000)) 58 invoice[cnt++]=int(a*100+b*100+c*100); 59 } 60 memset(dp,0,sizeof(dp)); 61 for(i=0;i<cnt;i++) 62 for(j=int(q*100);j>=invoice[i];j--) 63 dp[j]=max(dp[j-invoice[i]]+invoice[i],dp[j]); 64 printf("%.2f\n",1.0*dp[int(q*100)]/100); 65 } 66 return 0; 67 }
others code:
1 #include<iostream> 2 using namespace std; 3 4 double sum[30]; 5 double table[30]; 6 7 int main() 8 { 9 double q,price; 10 int n,m; 11 int i,j; 12 char type; 13 double maxn,ans; 14 bool flag; 15 int id; 16 double a,b,c; 17 while(~scanf("%lf%d",&q,&n),n) 18 { 19 memset(sum,0,sizeof(sum)); 20 id=0; 21 for(i=0;i<n;i++) 22 { 23 scanf("%d",&m); 24 a=0; 25 b=0; 26 c=0; 27 flag=1; 28 for(j=0;j<m;j++) 29 { 30 getchar(); 31 scanf("%c:%lf",&type,&price); 32 if(type=='A') 33 a+=price; 34 else if(type=='B') 35 b+=price; 36 else if(type=='C') 37 c+=price; 38 else 39 flag=false; 40 } 41 if(a>600||b>600||c>600||a+b+c>1000) 42 flag=false; 43 if(flag) 44 sum[id++]=a+b+c; 45 } 46 //-------------------------------------------没看懂----------------------------------------------------------------------------------- 47 memset(table,0,sizeof(table)); 48 ans=0; 49 for(i=0;i<id;i++) 50 { 51 maxn=0; 52 for(j=0;j<i;j++) 53 { 54 if((table[j]>maxn)&&(table[j]+sum[i]<=q)) 55 maxn=table[j]; 56 } 57 table[i]=maxn+sum[i]; 58 if(table[i]>ans) 59 ans=table[i]; 60 } 61 //-------------------------------------------没看懂----------------------------------------------------------------------------------- 62 printf("%.2f\n",ans); 63 } 64 return 0; 65 }
If you have any questions about this article, welcome to leave a message on the message board.
Brad(Bowen) Xu
E-Mail : maxxbw1992@gmail.com