这里背包容量为可以报销的张数
状态转移方程
dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+v[i])
表示,前i件物品放在容量为j的背包中
另法,这个题似乎还可以将数据乘以100化为整数去计算,但是感觉不太正确,因为题目中未告知输入数据的精度。。。
#include<iostream>
#include<fstream>
#include<set>
#include<stack>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MAX=0xfffffff;
double v[33],dp[33];
double A,B,C;
int main( )
{
//freopen("in.txt","r",stdin);
double q;
int n;
while(scanf("%lf %d",&q,&n)!=EOF&&n)
{
memset(dp,0,sizeof(dp));
memset(v,0,sizeof(v));
int len=0;
while(n--)
{
int n1;
scanf("%d",&n1);
A=B=C=0;
bool flag=1;
while(n1--)
{
char a;
double b;
scanf(" %c:%lf",&a,&b);
if(a=='A') A+=b;
else if(a=='B') B+=b;
else if(a=='C') C+=b;
else
{
flag=0;
}
}
if(flag==0) continue;
else
{
if(A+B+C<=1000&&A<=600&&B<=600&&C<=600)
v[len++]=A+B+C;
}
}
for(int i=0;i<len;i++)
for(int j=len;j>=1;j--)
{
if(dp[j-1]+v[i]<=q)
dp[j]=max(dp[j],dp[j-1]+v[i]);
}
double ans=0;
for(int j=len;j>=1;j--)
if(dp[j]>ans)
ans=dp[j];
printf("%.2lf\n",ans);
}
return 0;
}}