1. 程式人生 > >最大報銷額 (HDU - 1864,01揹包)

最大報銷額 (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;
}