题意:传送门
题解:这个题刚开始看了下,要求单项金额不超过600元,感觉题意描述的不是很清,还是浙大2007年的面试题,最后再看一遍,要求每个发票上只能有A B C,并且总金额不能超过1000,最后这个题它是要求每张发票上单项不能超过600元,这样就是输入每张发票处理一下,不合法的发票扔掉,合法的留下金额即可,最后以钱数做背包,实际钱数做价值滚一遍01背包即可,但是可能要说的这是浮点数,可以发现都乘以100,最后再除以100就行了。
一定仔细看题,不然浪费的都是青春。
附上代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=30+5;
const int maxc=3e6+5;
const int maxcost=3e6;
double q;
int n;
int ans[maxn],dp[maxc];
int main()
{
while(~scanf("%lf%d",&q,&n)){
if(n==0){
break;
}else{
int cnt;
double mm;
char c;
int num=1;
for(int i=1;i<=n;i++){
scanf("%d",&cnt);
double costa=0,costb=0,costc=0,sum=0;
bool flag=true;
for(int j=1;j<=cnt;j++){
scanf(" %c:%lf",&c,&mm);
sum+=mm;
if(c=='A'){
costa+=mm;
}else if(c=='B'){
costb+=mm;
}else if(c=='C'){
costc+=mm;
}else{
flag=false;
}
}
if(flag&&sum<=1000&&costa<=600&&costb<=600&&costc<=600){
ans[num++]=sum*100;
}
}
memset(dp,0,sizeof(dp));
for(int i=1;i<num;i++){
for(int j=(int)(q*100);j>=ans[i];j--){
dp[j]=max(dp[j],dp[j-ans[i]]+ans[i]);
}
}
printf("%.2f\n",(double)(dp[(int)(q*100)]/100.0));
}
}
return 0;
}