HDU - 1864 最大报销额 (背包)

题意:

现有一笔经费可以报销一定额度的发票。允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类),要求每张发票的总额不得超过1000元,每张发票上,单项物品的价值不得超过600元。现请你编写程序,在给出的一堆发票中找出可以报销的、不超过给定额度的最大报销额。

 

 

 

 

这个题本来没啥好写的。处理一下输入数据,然后就是个01背包。然而很坑的一点就是每张发票上是一类物品总价值不能超过600。题目描述的有问题,狠狠坑了我一把。真实。

由于数据给的是浮点数,需要乘以100转成整数才可以做。所以二维的01背包会MLE。

 

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define maxn 3000000 + 100

int main()
{
    double p;
    int n, a[40];
    int s[3];
    while(~scanf("%lf%d", &p, &n) && n)
    {
        int tot = 0, m = round(p*100);
        for (int i = 1; i <= n; i++)
        {
            int k;
            scanf("%d", &k);
            int sum = 0;
            bool flag = true;
            memset(s, 0, sizeof(s));
            for (int i = 1; i <= k; i++)
            {
                char type;
                double value;
                scanf(" %c:%lf", &type, &value);
                if (type != 'A' && type != 'B' && type != 'C') flag = false;
                    else if (s[type-'A']+= round(value*100) > 60000) flag = false;

                sum += round(value*100);
            }
            if (flag && sum <= 100000)
                a[tot++] = sum;
        }

        int f[maxn];
        memset(f, 0, sizeof(f));
        for (int i = 0; i < tot; i++)
            for (int j = m; j >= a[i]; j--)
                f[j] = max(f[j], f[j-a[i]]+a[i]);

        printf("%d.%02d\n", f[m]/100, f[m]%100);
    }
}

 

posted @ 2018-08-06 18:49  jvruodejrLS  阅读(162)  评论(0编辑  收藏  举报

Contact with me