针对规定的条件,对输入的数据进行一番处理之后,可以得到一个价值数组,代表每一张可以报销的发票能报销的额度
if(n == 0)break; getchar();//吃回车 v_idx = 0; for(int i = 0;i < n;i++) { int cnt; scanf("%d",&cnt); memset(limit,0,sizeof(limit)); double sum_cost = 0; double cost = 0; int flag = 1; char ch; for(int j = 0;j < cnt;j++) { scanf(" %c:%lf",&ch,&cost);//吃A getchar(); if(cost > 600 + eps)flag = 0; sum_cost += cost; limit[ch - 'A'] += cost; if(limit[ch-'A'] > 600 +eps)flag = 0; if(ch != 'A' && ch != 'B' && ch != 'C') flag = 0; } if(sum_cost > 1000 + eps || sum_cost > V + eps)flag = 0; //cout<<flag<<endl; if(flag) { v[v_idx++] = sum_cost; } }
但是这里首选的背包容量看似的报销额度,但是是浮点数,经常有这种的背包问题,这里就要变换一下背包的容量,可以变成发票的张数,看看报销多少张发表的时候的最大报销额可以满足条件
memset(dp,0,sizeof(dp)); //cout<<v_idx<<" "<<v[0]<<endl; for(int i = 0;i < v_idx;i++) { for(int j = v_idx;j >= 1;j--) { dp[j] = max(dp[j],dp[j-1]+v[i]); } } for(int i = v_idx;i >= 0;i--) { //cout<<dp[i]<<endl; if(dp[i] <= V + eps) { printf("%.2lf ",dp[i]); break; } }