DP - 倍增优化多重背包 - Cash Machine - POJ - 1276

DP - 倍增优化多重背包 - Cash Machine - POJ - 1276

题意:

多 组 测 试 用 例 , 每 组 包 括 价 值 上 限 m , 物 品 种 类 n , n 种 物 品 的 数 量 s 和 价 值 w e 。 多组测试用例,每组包括价值上限m,物品种类n,n种物品的数量s和价值we。 mnnswe

要 求 在 物 品 总 价 值 不 超 过 m 的 情 况 下 , 从 n 种 物 品 选 择 使 得 体 积 最 大 。 要求在物品总价值不超过m的情况下,从n种物品选择使得体积最大。 mn使

Sample Input:
735 3  4 125  6 5  3 350
633 4  500 30  6 100  1 5  0 1
735 0
0 3  10 100  10 50  10 10

Sample Output:
735
630
0
0

数据范围:

0 < = m < = 100000 , 0 < = n < = 10 , 0 < = s , w e < = 1000 。 T i m e   l i m i t : 1000 m s , M e m o r y   l i m i t : 10000 k B 0<=m<=100000,0<=n<=10,0<=s,we<=1000。\\Time\ limit:1000 ms,Memory\ limit:10000 kB 0<=m<=1000000<=n<=100<=s,we<=1000Time limit1000msMemory limit10000kB

题解:

将 价 值 上 限 视 作 背 包 体 积 , 物 品 价 值 同 样 视 作 物 品 体 积 , 那 么 问 题 就 转 化 为 多 重 背 包 问 题 : 计 算 从 n 种 物 品 当 中 选 择 总 体 积 不 超 过 m 的 物 品 的 最 大 收 益 。 将价值上限视作背包体积,物品价值同样视作物品体积,那么问题就转化为多重背包问题:\\计算从n种物品当中选择总体积不超过m的物品的最大收益。 nm

朴 素 的 多 重 背 包 O ( n m s ) 的 时 间 复 杂 度 显 然 容 易 出 事 , 这 里 用 倍 增 优 化 到 O ( n m l o g s ) 就 够 了 。 朴素的多重背包O(nms)的时间复杂度显然容易出事,这里用倍增优化到O(nmlogs)就够了。 O(nms)O(nmlogs)

——《背包问题模板


代码:

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

using namespace std;

const int N=100010;
int n,m,v[N],w[N],f[N];

int main()
{
    while(cin>>m>>n)
    {
        memset(f,0,sizeof f);
        int idx=0;
        for(int i=1;i<=n;i++)
        {
            int we,s;
            cin>>s>>we;
            int k=1;
            while(k<=s)
            {
                idx++;
                w[idx]=we*k;
                s-=k;
                k*=2;
            }
            if(s>0)
            {
                idx++;
                w[idx]=we*s;
            }
        }

        n=idx;
        for(int i=1;i<=n;i++)
            for(int j=m;j>=w[i];j--)
                f[j]=max(f[j],f[j-w[i]]+w[i]);

        cout<<f[m]<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值