最大报销额 HDU - 1864(01背包板题+坑题)

题意:传送门

题解:这个题刚开始看了下,要求单项金额不超过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;
}

猜你喜欢

转载自blog.csdn.net/zhouzi2018/article/details/86549198
今日推荐