最大报销额
原题链接https://vjudge.net/contest/348156#problem/G
本题难度主要在于数据的选择 之后就是01背包的问题
同时由于题目要求保留两位小数 所以我们需要将数据100来计算,由于会100所以要注意dp数组的大小。以保证小数位的精确 最后要注意double 的输出
#include<cstring>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
long long dp[3000005];
int main()
{
double q;
long long n;
char s;
long long v[105];
long long w[105];
while(~scanf("%lf %lld",&q,&n))
{
double sum;
long long j=0;
if(n==0)
{
break;
}
long long i;
for(i=0; i<n; i++)
{
long long t;
scanf("%lld",&t);
long long flag=1;
double a=0,b=0,c=0;
while(t--)
{
getchar();
scanf("%c:%lf",&s,&sum);
if(s=='A')
{
a+=sum;
}
else if(s=='B')
{
b+=sum;
}
else if(s=='C')
{
c+=sum;
}
else
{
flag=0;
}
if(a>600||b>600||c>600)
{
flag=0;
}
}
if(flag&&(a+b+c)<=1000)//如果该种情况可以选取就放入类型中
{
v[j]=(a+b+c)*100;
w[j]=(a+b+c)*100;
j++;
}
}
memset(dp,0,sizeof(dp));
long long c=q*100,z;
for(i=0; i<j; i++)
{
for(z=c; z>=w[i]; z--)
{
dp[z]=max(dp[z],dp[z-w[i]]+v[i]);//01背包找最大值
}
}
double sum1;
sum1=1.0*dp[c]/100;
printf("%.2lf\n",sum1);
}
return 0;
}