HDU 1786 Tempter of the Bone again(大数+完全背包)

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1786

题意

给出物品的数量n(1 < n < 10)和背包的容量m(0 < m < 1000000000),求使用最少的物品填满背包的情况,一定有解。每件物品的重量不超过100。

题解

首先,如果m超过100000的话,超过的部分用体积最大的物品尽量填满,然后剩下的部分使用完全背包求解。m不足100000的话,直接用完全背包求解即可。

为什么是100000:
物品最多为9件,每件物品最重不超过100,如果某一件物品使用超过100次的话,那么就可以用体积最大的那个物品代替一部分,因此剩下的容量应该为9x100x100,在这里取100000。

AC代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define INF 1e8
using namespace std;

const int maxn = 100000;
const int maxv = 100110;
int dp[maxv];
int goods[20];

int main()
{
    int n;long long int m;
    while(~scanf("%d%lld",&n,&m)&&n&&m)
    {
        for(int i = 1; i < maxv; i++)dp[i] = INF;
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &goods[i]);
        }
        sort(goods,goods+n);
        int ans = 0;
        if(m > maxn)
        {
            long long int v = m - maxn;
            ans += (v/goods[n-1]*3);
            v = maxn + v - v/goods[n-1]*goods[n-1];
            //cout << v << endl;
            for(int i = 0; i < n; i++)
            {
                for(int j = goods[i]; j <= v; j++)
                {
                    dp[j] = min(dp[j], dp[j-goods[i]] + 3);
                }
            }
            //cout << dp[v] <<endl;
            printf("%d\n", ans + dp[v]);
        }
        else
        {
            for(int i = 0; i < n; i++)
            {
                for(int j = goods[i]; j <= m; j++)
                {
                    dp[j] = min(dp[j], dp[j-goods[i]] + 3);
                }
            }
            printf("%d\n",dp[m]);
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值