1864 maximum reimbursement HDU 0-1 backpack

1864 maximum reimbursement HDU 0-1 backpack

The meaning of problems

Existing sum of money can be reimbursed a certain amount of the invoice. Invoice types include reimbursement allowed to buy the book (A type), stationery (Class B), the total travel (C Type), requires each invoice shall not exceed 1000, every invoice, not the value of the individual items of over $ 600 . Now you write a program to find a pile of invoices for reimbursement given, not to exceed the maximum reimbursement quotas degrees.

Here we must note that, as long as the total amount is greater than 1000, or the total amount of each category of greater than 600, or the invoice there are other categories of goods, it can not be reimbursed

Problem-solving ideas

This is a simple \ (0-1 \) backpack, the main aspect is that the preprocessing of the data.

Another point is the need integer array subscript, but this amount is floating point, how to do it? We found that the data entered here are retained two decimal places, so we can each amount \ (* 100 \) , so we are all the integers.

Some details, see code.

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=40;
const int maxm=4e5+7;
const int maxq=1000*30*100+7;
double rec[maxn];
double dp[maxq];
double q;
int n, m;
int main()
{
    while(scanf("%lf%d", &q, &n) && n!=0)
    {
        char type;
        int flag, cnt=0; //使用cnt来记录实际合法的发票个数
        while(n--)
        {
            double price, va=0, vb=0, vc=0;//总金额,A,B,C类的总金额
            flag=1; //一个标记
            scanf("%d", &m);
            while(m--)
            {
                scanf(" %c:%lf", &type, &price);
                if(flag==0)//如果标记为0的话,说明前面有不合法的数据,这个发票也就作废了
                    continue;
                if(type=='A')
                    va+=price;
                else if(type=='B')
                    vb+=price;
                else if(type=='C')
                    vc+=price;
                else flag=0;
            }
            //下面会再次进行判断
            if(flag==1 && va<=600.0 && vb<=600.0 && vc<=600.0 && (va+vb+vc)<=1000.0)
            {
                rec[++cnt]=va+vb+vc;
            }
        }
        memset(dp, 0, sizeof(dp));
        int max_val=int(q*100);//最大金额化成整数
        for(int i=1; i<=cnt; i++)
        {
            for(int j=max_val; j>=int(rec[i]*100); j--) //每张发票的金额也要化成整数
            {
                dp[j]=max(dp[j-int(rec[i]*100)]+rec[i], dp[j]);
            }
        } 
        printf("%.2lf\n", dp[max_val]);//注意输出格式,要求小数点后两位。
    }
    return 0; 
}

Guess you like

Origin www.cnblogs.com/alking1001/p/11875991.html