题目链接
题意:给出发票,要求报销的发票种类仅限于’A’,’ B’,'C’三种,且每张发票总额不得超过1000元,每张发票的单项物品价格不得超过600元。按以上要求找到最大的报销费。
思路:
1.给的数据价格是小数类型的,为了方便,可以先把小数类型的都乘100变成整数;
2.每一张发票的总额算出来并且判断总额是否小于等于100000,单项物品价格是否小于等于60000,满足就把结果存放在mo[i]数组里;
3.最后再利用dp求出最后的结果,最后记得要除以100.0。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stack>
#include<cstring>
#include<map>
using namespace std;
int dp[3000050];
int main()
{
double q,p;
int n,m,sum,pp,a,b,c,mo[35],f,d;
char s;
while(~scanf("%lf %d",&q,&n)&&n!=0){
sum=q*100;
d=0;
memset(mo,0,sizeof(mo));
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++){
scanf("%d",&m);
a=b=c=0;
f=0;
for(int j=0;j<m;j++){
scanf(" %c:%lf",&s,&p);
pp=p*100;
if(s=='A')a+=pp;
else if(s=='B')b+=pp;
else if(s=='C')c+=pp;
else f=1;
}if(a+b+c<=100000&&a<=60000&&b<=60000&&c<=60000&&f==0){mo[d]=a+b+c;d++;}//注意这,不要放在上一个for里,一行数据是一次报销,如果放在for里就一行里的一个成一个报销了
}
for(int i=0;i<d;i++){
for(int j=sum;j>=dp[i];j--){
if(mo[i]<=j)
dp[j]=max(dp[j],dp[j-mo[i]]+mo[i]);
}
}printf("%.2f\n",dp[sum]/100.0);
}
return 0;
}