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

首先强调不超过600元的是一张发票上同一类商品的额度总和,而题意描述的是单项物品,坑!

输入有空格字符,需要注意一下。然后每一张发票输入完之后,判断是否满足报销条件,如果满足则存入w数组。

之后就是一个01背包问题了,只不过这里的价值和花费相等,只需要一个数组存下即可。不过利用dp数组进行状态转移的时候需要注意,因为最后的精度要求是小数点后两位,所以要遍历到每一种状态的话,要将整体的数据都扩大一百倍,否则当前状态没法用数组下标表示。最后将结果再缩小100倍即可。

代码如下(未精简,略冗长):

#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio>

using namespace std;

#define mem(a, i) memset(a, i, sizeof(a))
#define INF 0x3f3f3f3f

int dp[4999000];

int main()
{
    //freopen("in.txt", "r", stdin);
    int n;
    double q;
    while(cin >> q >> n && n)
    {
        int w[1010];
        int m;
        char s, c;
        mem(w, 0);
        for(int i = 1; i <= n; ++ i)
        {
            cin >> m;
            bool flag = true;
            double h, A = 0, B = 0, C = 0, sum = 0;
            for(int j = 0; j < m; ++ j)
            {
                c = getchar();
                s = getchar();
                c = getchar();
                if(!(s == 'A' || s == 'B' || s == 'C'))
                {
                    flag = false;
                }
                cin >> h;
                if(s == 'A')
                {
                    A += h;
                }
                else if(s == 'B')
                {
                    B += h;
                }
                else if(s == 'C')
                {
                    C += h;
                }
            }
            if(A > 600 || B > 600 || C > 600)
            {
                flag = false;
            }
            else
            {
                sum += (A + B + C);
            }
            if(flag && sum <= 1000)
            {
                w[i] = (sum * 100);
            }
            else
            {
                w[i] = INF;
            }
        }
        mem(dp, 0);
        int p = (q * 100);
        for(int i = 1; i <= n; ++ i)
        {
            for(int j = q * 100; j >= 0; --j)
            {
                if(j < w[i])
                {
                    dp[j] = dp[j];
                }
                else
                {
                     dp[j] = max(dp[j - w[i]] + w[i], dp[j]);
                }
            }
        }
        printf("%.2lf\n", dp[p] * 1.0 / 100);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/gx1313113/article/details/81512158
今日推荐