HDU-1864 最大报销额

本文介绍了一个关于0-1背包问题的编程解决方案,重点在于如何处理包含小数金额的发票,通过将其转换为整数形式来简化问题,并实现一个有效的DP算法来找到最大报销额度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

using namespace std;

const int q_max = 1000 * 30 * 100 + 5;
const int n_max = 30 + 5;

double dp[q_max];
double abc[3];
double price[n_max];
int price_temp[n_max];
double q;
int q_temp;
int n, m;
char letter;
double value, sum;
int flag, pos;

void DP()
{
    memset(dp, 0, sizeof(dp));
    for(int i = 0; i < pos; i ++)
        price_temp[i] = price[i] * 100;
    q_temp = q * 100;
    for(int i = 0; i < pos; i ++)
        for(int j = q_temp; j >= price_temp[i]; j --)
            dp[j] = max(dp[j], dp[j - price_temp[i]] + price_temp[i]);
}
int main()
{
    while(~scanf("%lf %d", & q, & n))
    {
        if(!n)
            break;
        memset(price, 0, sizeof(price));
        pos = 0;
        for(int i = 0; i < n; i ++)
        {
            scanf("%d", & m);
            flag = 1;
            memset(abc, 0, sizeof(abc));
            sum = 0;
            while(m --)
            {
                scanf(" %c:%lf", & letter, & value);
                sum += value;
                if(letter != 'A' && letter != 'B' && letter != 'C')
                {
                    flag = 0;
                    continue;
                }
                abc[letter - 'A'] += value;
                if(sum > 1000 || abc[letter - 'A'] > 600)
                    flag = 0;
            }
            if(flag)
            {
                price[pos] = sum;
                pos ++;
            }
        }
        DP();
        printf("%.2f\n", dp[q_temp] * 1.0 / 100);
    }
    return 0;
}

题意:

(摘自 键盘上的舞者)
先给出最大的报销额和发票的张数,然后下面是n张发票,每张发票先给出发票上物品的个数,然后给出每种物品和物品的价格

注意:
1.只有a,b,c三种物品可以报销,含有其他物品的发票作废

2.单样物品的价值不能超过600

3.每张发票总价值不能超过1000

输出最大价值

题解:

将所有的小数化为整数,这样就成了最基础的0-1背包问题。但是判断的时候要小心…就因为中间判断郁闷到现在。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值