这个题目有毒。。一开始就注意到了需要统计A、B、C三个的数值,但是他说单个物品不超过600实在是误导。。。
这是一个dp,转换方程
dp[j]=max(dp[j-(int)(100*value[i])]+value[i],dp[j])
其中value是统计的合法报销的帐目、dp[i]表示价格*100(因为精确到两位,所以乘以100)可以得到的最大报的账目。简单的背包问题。
#include<bits/stdc++.h>
#define input freopen("input.txt","r",stdin)
using namespace std;
float sum;
float dp[3000010];
float check[3],value[40];
int main()
{
input;
int n,i,j,m,flag,pos;
char c;
float key;
while(cin>>sum>>n)
{
if(n==0)
break;
for(pos=1,i=1;i<=n;i++)
{
memset(check,0,sizeof(check));
flag=1;
scanf("%d",&m);
for(j=1;j<=m;j++)
{
getchar();
c=getchar();
getchar();
cin>>key;
if(c!='A'&&c!='B'&&c!='C')
{
flag=0;
}
check[c-'A']+=key;
if(check[c-'A']>600)
{
flag=0;
}
if(check[0]+check[1]+check[2]>1000)
{
flag=0;
}
}
if(flag)
{
value[pos++]=check[0]+check[1]+check[2];
}
}
memset(dp,0,sizeof(dp));
for(i=1;i<pos;i++)
{
for(j=(int)(sum*100);j>=(int)(100*value[i]);j--)
{
dp[j]=max(dp[j-(int)(100*value[i])]+value[i],dp[j]);
}
}
printf("%.2lf\n",dp[(int)(sum*100)]);
}
return 0;
}
代码不好,欢迎指正