hdu_1864

来源:互联网 发布:c语言float是什么意思 编辑:程序博客网 时间:2024/06/12 23:35

/*

  对于给定的账单,我们要确定它报销还是不会被报销,这样我们就把这这个问题化为了一个账单,一个总价值的物体,

  对于给定的物体我们把他想为价值和体积相等的物体装进给定的报销金额里面去,运用01背包就可以算出dp[n][0...p],中价值最多为多少。

  其中对于dp[i][j]的意义为前i中物品最多报销多少的金额,j是给定的最大报销金额。

  状态转移方程为dp[i[j]]=max(dp[i-][j],dp[i-1][j-a[i]]+a[i]);


注意:对于每一类的物品的总价值不可超过600,对于账单总额不可超过1000。

*/



#include <iostream>

#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int dp[3000005];
int a[40];
int main()
{
    double p;
    int n;
    while(cin>>p>>n){
        if(!n)
            break;
        p*=100; int p1=p;


        double sum;
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++){
            double str[3]={0};
            sum=0;

            double cnt; cin>>cnt;

            for(int j=1;j<=cnt;j++){

                double tmp;
                char c[2];

                cin>>c[0]>>c[1]>>tmp;
                //cout<<c[0]<<c[1]<<tmp<<endl;
                if(sum==-1)
                    continue;
                sum+=tmp;
                if(c[0]=='A')
                    str[0]+=tmp;
                else if(c[0]=='B')
                    str[1]+=tmp;
                else if(c[0]=='C')
                    str[2]+=tmp;
                else
                    sum=-1;
                if(str[0]>600||str[1]>600||str[2]>600||sum>1000)
                    sum=-1;
            }
            sum*=100;
            a[i]=sum;
            //cout<<"a["<<i<<"]="<<a[i]<<endl;
        }
        memset(dp,0,sizeof(dp));

        //cout<<p1<<endl;
        for(int i=1;i<=n;i++){
            if(a[i]>0)
                for(int j=p1;j>=a[i];j--){
                    dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
                }
        }
        printf("%.2lf\n",dp[p1]*0.01);
    }
    //cout << "Hello world!" << endl;
    return 0;
}

0 0