hdoj 1864 最大報銷額【0-1揹包變形】

最大報銷額

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 21045    Accepted Submission(s): 6308


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時,全部輸入結束,相應的結果不要輸出。
 

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   |   We have carefully selected several similar problems for you:  1231 1087 2844 2159 1505 
 

Statistic | Submit | Discuss | Note

代碼:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define max(a,b) a>b?a:b 
using namespace std;
int a[30];
int dp[3000005];
int judge(char c)
{
	if(c=='A') return 1;
	if(c=='B') return 2;
	if(c=='C') return 3;
	return 0;
}
int main()
{
	double Q;
	int N;
	while(scanf("%lf%d",&Q,&N)&&N)
	{
		int num=0;
		int limit=Q*100;//輸入之後就直接擴大100倍轉化成整數 
		for(int i=0;i<N;i++)
		{
			int m;int flag=1;
			scanf("%d",&m);
			int sum1,sum2,sum3;
			sum1=sum2=sum3=0;
			while(m--)
			{
				char op;double need;
				getchar();//這個不能丟! 
				scanf("%c:%lf",&op,&need);
				need=need*100;
				int x=need;//擴大100倍轉化成整數 
				if(!flag)//在不符合條件的話就捨去 
					continue;
				if(judge(op)==0) flag=0;//不是A,B,C三種之內的,不報銷!
				if(judge(op)==1) sum1+=x;
				if(judge(op)==2) sum2+=x;
				if(judge(op)==3) sum3+=x;
				if((sum1>60000||sum2>60000||sum3>60000)) flag=0;//如果有一個小於600都不報銷 
				if(!flag) 
					continue; //因爲還要將輸入完成,所以要繼續循環,而不能跳出 
			}
			if(sum1+sum2+sum3<=limit&&flag)//在之前輸入都滿足條件的前提下才保存到a中等着報銷 
				a[num++]=sum1+sum2+sum3;
		}
		memset(dp,0,sizeof(dp));//剛開始報銷爲0 
		for(int i=0;i<num;i++)//在limit的限制下能得到的最大的報銷 
		{
			for(int j=limit;j>=a[i];j--)
			{
				dp[j]=max(dp[j],dp[j-a[i]]+a[i]); 
			}
		}
		printf("%.2lf\n",dp[limit]/100.0);//按題意輸出 
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章