#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[4000000];//数组容量表示最大的总额,这里尽量开大了
int main()
{
int n,i,j,m,sum,flag,sum_all;
char type;
double price,q;
int a,b,c;
int g[40];//每张符合要求的发票的总额将存在里面
while(scanf("%lf %d",&q,&n)&&n!=0)
{
sum_all=0;
memset(g,0,sizeof(g));
for(i=1;i<=n;i++)
{
scanf("%d",&m);
sum=0;flag=1;
a=b=c=0;
for(j=0;j<m;j++)
{
scanf(" %c:%lf",&type,&price);
if(type=='A')
{
a+=(int)(price*100);//便于利用01背包的解决办法,全部扩大100倍,后同
}
else if(type=='B')
{
b+=(int)(price*100);
}
else if(type=='C')
{
c+=(int)(price*100);
}
else
{
flag=0;
}
sum+=(int)(price*100);
}
if(sum>100000||a>60000||b>60000||c>60000||!flag)
{
a=b=c=0;
}
g[i]=a+b+c;
sum_all+=g[i];
}
memset(f,0,sizeof(f));
f[0]=1;
for(i=1;i<=n;i++)
{
for(j=sum_all;j>=g[i];j--)
{
if(!f[j]&&f[j-g[i]]==1)
{
f[j]=1;
}
}
}//01背包的处理方式
for(i=sum_all;i>=0;i--)
{
if(f[i]==1&&i<=(int)(q*100))
{
printf("%.2lf\n",((double)i)/100);
break;
}
}
}
return 0;
}
[acm]动态规划-最大报销额
最新推荐文章于 2021-08-30 22:40:42 发布