http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=187#problem/G
该题要注意的就是每张单子A种类的总和不能大与600,同样B,C类也一样,还有注意如果不是A,B,C类的不可以报销;
该题就是要把浮点型变成整数这样才能用01背包,这里就只要乘以100就可以了。
这题考的背包很简单,就是输入的金额为背包的容积,债券既是物体的体积又是物体的利润。就是处理输入的数据有点麻烦,这是我所不擅长的。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int dp[3000001],w[31];
int main()
{
int n,V,m,flag,tt;
double sum,price;
char c;
while(scanf("%lf%d",&sum,&n)!=EOF)
{
if(n==0) break;
sum=sum*100;
V=(int)sum;
tt=0;
int t,ta=0,tb=0,tc=0,x;
for(int i=1;i<=n;i++)
{
sum=0;
ta=0,tb=0,tc=0;
scanf("%d",&m);
flag=0;
while(m--)
{
scanf("%*c%c:%lf",&c,&price);
price=price*100;
x=(int)price;
if(flag==0)
{
if((c=='A')||(c=='B')||(c=='C'))
{
if(c=='A'&&ta+x<=60000)
{
ta=ta+x;
}
else if(c=='B'&&tb+x<=60000)
{
tb=tb+x;
}
else if(c=='C'&&tc+x<=60000)
{
tc=tc+x;
}
else flag=1;
}
else flag=1;
}
}
t=ta+tb+tc;
if(flag==0&&t<=100000)
{
w[tt++]=t;
}
}
memset(dp,0,sizeof(dp));
for(int i=0;i<tt;i++)
{
for(int j=V;j>=w[i];j--)
{
if(dp[j-w[i]]+w[i]>dp[j])
dp[j]=dp[j-w[i]]+w[i];
}
}
double money=dp[V]/100.0;
printf("%.2lf\n",money);
}
return 0;
}