HDU 1864最大报销额 01背包

我看到网上好多都是将物品的价值,背包容量扩大一百倍全部转化为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;
}

猜你喜欢

转载自blog.csdn.net/chenyume/article/details/83210562
今日推荐