HDU1864 最大报销额 [背包dp-浮点数]

来源:互联网 发布:网络创世纪手游 编辑:程序博客网 时间:2024/06/01 10:13

题意是给定最大的报销额度,确定最多能报多少发票。
发票有一些小的限制(坑坑坑)
和 裸01背包的区别在于物体的价值的是浮点数,但此题只需要精确两位小数,所以先*100 再/100处理。

#include<iostream>#include<string>#include<cstdio>#include<cstring>#include<bitset>#include<algorithm>#include<map>#include<set>#include<queue>#include<vector>#include<cstdlib>#include<list>#include<stack>#include<cmath>#include<iomanip>using namespace std;typedef long long LL;LL dp[3000005];int w[35];int main(){    ios::sync_with_stdio(false);    #ifndef ONLINE_JUDGE    freopen("input.txt", "r", stdin);    #endif // ONLINE_JUDGE    int k;    double M;    while(cin >> M >> k)    {        if(k == 0) break;        memset(dp, 0, sizeof(dp));        int m = 0;        int lim= (int)(M*100);        for(int i = 0; i < k; ++i)        {            double price[5];            price[0] = price[1] = price[2] = 0.0;            int num;            cin >> num;            int flag = 1;            while(num--)            {                char t, temp;                cin >> t >> temp;                double wei;                cin >> wei;                if(t != 'A' && t != 'B' && t != 'C')                    flag = 0;                else price[t-'A'] += wei;            }            if(!flag) continue;            if(price[0] > 600 || price[1] > 600 || price[2] > 600) continue;            if(price[0] + price[1] + price[2] > 1000) continue;            w[m++] = (price[0] + price[1] + price[2])*100;        }        for(int i = 0; i < m; ++i)        {            for(int j = lim; j >= w[i]; --j)                dp[j] = max(dp[j], dp[j-w[i]]+w[i]);        }        LL ans = 0;        for(int i = 1; i <= lim; ++i)            ans = max(ans, dp[i]);        cout.setf(ios::fixed);        cout << fixed << setprecision(2) << (double)ans/100 << endl;    }    return 0;}