解题思路:
这题真是WA到哭泣,感觉一个人拉高了整体的错误率,其实题目思路还是清晰的,但是题目中条件很多容易漏掉,这里罗列一下。
1.每张发票的报销类型只能为A,B,C,有其他类型则此发票作废
2.每张发票的每种报销类型的报销额相加后要<=1000,若大于则此发票作废
3.每张发票的每种报销类型的报销额都不能超过600,即A<=600,B<=600,C<=600
上述条件只要有一个不符合这张发票就不用被记录啦,然后就看成重量和价值是相等的01背包做就可以啦,但是因为背包是整数,所以记得把报销额都转换成整数。
代码:
扫描二维码关注公众号,回复:
2450294 查看本文章
#include<bits/stdc++.h>
#define t 100
using namespace std;
int dp[3000005],v[3000005];
int main()
{
double Q;
int N;
while(~scanf("%lf%d",&Q,&N) && N!=0){
memset(v,0,sizeof(v));
memset(dp,0,sizeof(dp));
int i=0,j,k=0,q;
double p;
char s1;
while(N--){
int n,flag=1;
double sum=0,a=0,b=0,c=0;
scanf("%d",&n);
while(n--){
scanf(" %c:%lf",&s1,&p);
if(s1=='A')a=a+p;
else if(s1=='B')b=b+p;
else if(s1=='C')c=c+p;
else flag=0;
}
sum=a+b+c;
if(flag && sum<=1000 && a<=600 && b<=600 && c<=600)v[k++]=(int)(sum*t);
}
q=(int)(Q*t);
for(i=0;i<k;i++){
for(j=q;j>=v[i];j--){
dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
}
}
printf("%.2f\n",dp[q]/100.0);
}
return 0;
}