汉语题。
思路一看就是经典的01背包问题,背或者不背呢?===
注意的点:1. 字符处理 2.条件判断 3.精度与范围控制 4.经典背包计算
相对来说第三点是不容易想到的,精度的控制这么巧妙,因为在用一维数组控制dp的时候i,j是int类型,
也就是容量要求是int类型,题中是double类型,所以先扩大100倍,保留两位小数。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = 3000050;
double dp[maxn];
int money[40];
int main()
{
//freopen("in.txt","r",stdin);
double Q;
int n;
while(scanf("%lf%d",&Q,&n) != EOF){
if(n == 0)
break;
memset(dp,0,sizeof(dp));
memset(money,0,sizeof(money));
int l = 0;
int w = Q*100;
char c;
int dn;
for(int i = 0;i < n; i++){
scanf("%d",&dn);
//printf("dn = %d ",dn);
getchar();
int flag = true;
double A = 0,B = 0,C = 0,temp;
for(int j = 0;j < dn ;j++){
scanf("%c:%lf",&c,&temp);
// printf(" %c:%lf ",c,temp);
if(c == 'A'){
A += temp*100;
}
else if(c == 'B'){
B += temp*100;
}
else if(c == 'C'){
B += temp*100;
}
else flag = false;
getchar();
}
if(flag && A <= 60000 && B <= 60000 && C <= 60000 && A+B+C <= 100000)
money[l++] = A+B+C;
//printf("\n");
}
for(int i = 0;i < l; i++){
for(int j = w;j >= money[i]; j--){
dp[j] = max(dp[j],dp[j-money[i]] + money[i]);
}
}
printf("%.2f\n",dp[w]/100.0);
}
return 0;
}