我看到网上好多都是将物品的价值,背包容量扩大一百倍全部转化为int再最后输出时转化为double输出,所以我想可不可以直接用总支票数作为背包容量,显然是可以的。
每一张支票的重量为1,权值即是报销额度,可以通过计算,直接筛除不符合条件的支票;
由于有一个最大的总报销额,所以1. dp[j-1]+val[i]<=Q(最大报销额),则 dp[j]=max(dp[j],dp[j-1]+val[i]);
2. 否则,dp[j]=dp[j];
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const double epos=1e-8;
const int maxn=39;
double dp[maxn];
double vall[39];
bool cmp(const double& x,const double& y){return x>y;}
int main(){
double Q,val;
int n;
char c,d;
int m;
while(scanf("%lf%d",&Q,&n)!=EOF&&n){
memset(dp,0,sizeof(dp));
int t=0;
for(int i=0;i<n;i++){
scanf("%d",&m);
int flag=1;
double aa=0,bb=0,cc=0;
while(m--){
getchar();
scanf("%c%c%lf",&c,&d,&val);
if(c=='A')
aa+=val;
else if(c=='B')
bb+=val;
else if(c=='C')
cc+=val;
else
flag=0;
}
//将不符合要求的支票删掉;
if(flag==1&&aa<=600&&bb<=600&&cc<=600&&(aa+bb+cc)<=1000&&(aa+bb+cc)<=Q)
vall[t++]=aa+bb+cc;
}
for(int i=0;i<t;i++)
for(int j=t;j>=1;j--)
if(dp[j-1]+vall[i]<=Q)
dp[j]=max(dp[j],dp[j-1]+vall[i]);
else
dp[j]=dp[j];
//printf("%.2lf\n",dp[t]);
sort(dp+1,dp+1+t,cmp);
printf("%.2lf\n",dp[1]);
}
return 0;
}