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
123.50 1000.00 1200.50
题意:先给出最大的报销额和发票的张数,然后下面是n张发票,每张发票先给出发票上物品的个数,然后给出每种物品和物品的价格
注意:1.只有a,b,c三种物品可以报销,含有其他物品的发票作废
2.丹阳物品的价值不能超过600
3.每张发票总价值不能超过1000
输出最大价值
思路:也是一道01背包果题,知道了上诉条件之后要写也不是难事
代码:
#include <stdio.h> #include <algorithm> #include <string.h> using namespace std; int dp[3000050];//由于每张发票不超过1000,最多30张,扩大100倍数后开这么大即可 int main() { char ch; double x,y; int sum,a,b,c,money[35],v; int t,i,j,k; while(~scanf("%lf%d",&x,&t),t) { sum = (int)(x*100);//将小数化作整数处理 memset(money,0,sizeof(money)); memset(dp,0,sizeof(dp)); int l = 0; for(i = 0; i<t; i++) { scanf("%d",&k); a = b = c = 0; int flag = 1; while(k--) { scanf(" %c:%lf",&ch,&y); v = (int)(y*100); if(ch == 'A' && a+v<=60000) a+=v; else if(ch == 'B' && b+v<=60000) b+=v; else if(ch == 'C' && c+v<=60000) c+=v; else flag = 0; } if(a+b+c<=100000 && a<=60000 && b<=60000 && c<=60000 && flag)//按题意所说,必须满足这些条件 money[l++] = a+b+c; } for(i = 0; i<=l; i++) { for(j = sum; j>=money[i]; j--) dp[j] = max(dp[j],dp[j-money[i]]+money[i]); } printf("%.2lf\n",dp[sum]/100.0); } return 0; }