1. 程式人生 > >hdoj - 1864 最大報銷額

hdoj - 1864 最大報銷額

測試用例 content div left 兩個 英文字母 code ... tput

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

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1864

題目中給的數據是浮點型,背包問題處理的是整形數據,所以先*100將其轉化為整形。

題目的輸入數據比較復雜,我門需要先選出符合要求的發票,然後就是在符合要求的發票中選取一些發票,使得總金額最接近給的金額。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

int dp[3000005];
int a[3000005];
int main()
{
    int n;
    double q;
    
while(scanf("%lf %d",&q,&n) && n != 0) { int m; int num = 0; int maxx=(int)(q*100); for(int i = 0;i<n;i++) { scanf("%d",&m); char tc; double pi; double va,vb,vc; va
=vb =vc = 0; int biaoji=1; for(int j = 0;j<m;j++) { scanf(" %c:%lf",&tc,&pi); if(tc == A) { va = va + pi; }else if(tc == B) { vb = vb + pi; }else if(tc == C) { vc = vc + pi; }else { biaoji = 0; } } if(biaoji==1 && va<=600 && vb<=600 && vc<=600 && va+vb+vc<=1000) { a[num] = (int)((va+vb+vc)*100); num++; } } memset(dp,0,sizeof(dp)); for(int i = 0;i<num;i++) { for(int j = maxx;j>=a[i];j--) { dp[j] = max(dp[j],dp[j-a[i]]+a[i]); } } printf("%.2lf\n",(dp[maxx])/100.0); } return 0; }

hdoj - 1864 最大報銷額