题目链接

把重量表示为\(a\times2^b\)的形式,然后按\(b\)排序。

从高到低枚举每一位,\(f[i]\)表示当前位容量为\(i\)时的最大价值(容量即\(a\times2^{bit}\))。对于同一位,直接\(01\)背包就行了。

如何转移到下一位?\(f[i]\)转移到\(f[i\times2+\text{W在这一位是否为1}]\)。注意到每一位的容量不会超过\(n\times a_{max}=1000\),所以再对\(1000\)取\(\min\)即可。

//840kb	64ms
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=1005; struct Node
{
int a,b,val;
bool operator <(const Node &x)const
{
return b>x.b;
}
}A[N]; inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
void Solve(int n,int m)
{
static int f[N],g[N];
int mx=0;
for(int i=1,a,b; i<=n; ++i)
{
a=read(), A[i].val=read();
for(b=0; b<30&&!(a&1); ++b,a>>=1);
mx=std::max(mx,a), A[i].a=a, A[i].b=b;
}
std::sort(A+1,A+1+n); const int lim=n*mx;
memset(f,-0x3f,sizeof f);
f[0]=0, A[n+1].b=-1;
for(int i=30,now=1; ~i; --i)
{
memset(g,-0x3f,sizeof g);
for(int j=0,p; j<=lim; ++j)
p=std::min((j<<1)+(m>>i&1),lim), g[p]=std::max(g[p],f[j]);
memcpy(f,g,sizeof f);
for(; A[now].b==i; ++now)
for(int ai=A[now].a,vi=A[now].val,j=0; j<=lim-ai; ++j)
f[j]=std::max(f[j],f[j+ai]+vi);//f[i]:剩余容量为i
}
int ans=0;
for(int i=0; i<=lim; ++i) ans=std::max(ans,f[i]);
printf("%d\n",ans);
} int main()
{
int n,m;
while(n=read(),m=read(),n!=-1&&m!=-1) Solve(n,m);
return 0;
}

BZOJ.1190.[HNOI2007]梦幻岛宝珠(分层背包DP)的更多相关文章

  1. 【BZOJ1190】[HNOI2007]梦幻岛宝珠 分层背包DP

    [BZOJ1190][HNOI2007]梦幻岛宝珠 Description 给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值. ...

  2. BZOJ 1190 [HNOI2007]梦幻岛宝珠(背包)

    1190: [HNOI2007]梦幻岛宝珠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1385  Solved: 798[Submit][Stat ...

  3. [BZOJ 1190][HNOI2007]梦幻岛宝珠

    1190: [HNOI2007]梦幻岛宝珠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1057  Solved: 611[Submit][Stat ...

  4. luogu3188/bzoj1190 梦幻岛宝珠 (分层背包dp)

    他都告诉你能拆了 那就拆呗.把每个重量拆成$a*2^b$的形式 然后对于每个不同的b,先分开做30个背包 再设f[i][j]表示b<=i的物品中 容量为$ j*2^i+W\&((1< ...

  5. 1190: [HNOI2007]梦幻岛宝珠 - BZOJ

    Description 给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值. 数据范围:N<=100;W<=2^30 ...

  6. 【bzoj 1190】梦幻岛宝珠(DP)

    这题是在01背包问题的基础上,扩充了重量,需要用时间换空间. 思路: 1.仔细看题,注意到重量wi为a*2^b(a<=10,b<=30),很容易想到要按 b 分开做背包的DP.接下来的重点 ...

  7. luogu 3188 [HNOI2007]梦幻岛宝珠

    LINK:梦幻岛宝珠 时隔多日 我再次挑战这道题.还是以失败告终. 我觉得这一道背包真的有点难度 这是一个数量较少 但是价值和体积较大的背包. 通常的01背包 要不就是体积小 要么是价值小 但这道题给 ...

  8. [HNOI2007]梦幻岛宝珠 「套路:分层 $DP$」

    显然直接 \(01\) 背包会超时并且超空间 套路:分层 \(DP\) 「考虑将每个子结构看作一层(也就是包含了不止 \(1\) 个物品的信息),并且大层不会对小层造成影响,可以考虑先进行每一层的自我 ...

  9. bzoj1190 [HNOI2007]梦幻岛宝珠 背包

    题目 https://lydsy.com/JudgeOnline/problem.php?id=1190 题解 好神仙的一道题啊. 既然 \(w_i = a_i\cdot 2^{b_i}\),那么不妨 ...

随机推荐

  1. SpringMVC使用Burlap发布远程服务

    参考这篇文章https://www.cnblogs.com/fanqisoft/p/10283156.html 将提供者配置类中的 @Bean public HessianServiceExporte ...

  2. C# ASP.NET MVC 配置允许跨域访问

    在web.config文件中的 system.webServer 节点下 增加如下配置 <httpProtocol> <customHeaders> <add name= ...

  3. 详解Jquery选择器

    1.常见的选择器 id,类,标签选择器. $("#a1") $(".myclass") $("div") 2.组合选择器 $("# ...

  4. Pytorch 之 backward

    首先看这个自动求导的参数: grad_variables:形状与variable一致,对于y.backward(),grad_variables相当于链式法则dz/dx=dz/dy × dy/dx 中 ...

  5. Excel中快捷键Ctrl+End覆盖过多

    Sub dd() MsgBox ActiveSheet.UsedRange.Address End Sub 更简单的方法:通过快捷键,选中空白行/列,然后删除行/列,保存,OK!

  6. UML和模式应用4:初始阶段(6)--迭代方法中如何使用用例

    1.前言 用例是UP和其他众多迭代方法的核心.UP提倡用例驱动开发. 2. 迭代方法中如何使用用例 功能需求首先定义在用例中 用例是迭代计划的重要部分,迭代是通过选择一些用例场景或整个用例来定义的 用 ...

  7. c语言的重构、清理与代码分析图形化浏览工具: CScout

    网址: https://www.spinellis.gr/cscout/ https://www2.dmst.aueb.gr/dds/cscout/index.html https://github. ...

  8. CentOS如何设置终端显示字符界面区域的大小

    红框内的文字本应该在上一行后方,调了stty也不行, stty size的值变化,但显示还是没变化 后来参考http://www.jb51.net/os/RedHat/522217.html 修改 / ...

  9. 转载:gc的概念,如果A和B对象循环引用,是否可以被GC?

    原文:https://www.cnblogs.com/zhchoutai/p/6784929.html ①首先说一下,GC里边在JVM其中是使用的ROOT算法,ROOT算法,什么称作为ROOT呢,就是 ...

  10. 中文多分类 BERT

    直接把自己的工作文档导入的,由于是在外企工作,所以都是英文写的 Steps: git clone https://github.com/google-research/bert prepare dat ...