bzoj1190 [HNOI2007]梦幻岛宝珠 背包
题目
https://lydsy.com/JudgeOnline/problem.php?id=1190
题解
好神仙的一道题啊。
既然 \(w_i = a_i\cdot 2^{b_i}\),那么不妨按照 \(b_i\) 来分组,每一组内部先做一个 01 背包,记为 \(f[i][j]\)。
然后考虑怎么求出最后的总答案。
下面就是很妙的部分了:
\(dp[i][j]\) 表示前 \(i\) 位中,容量 \(\leq j\cdot 2^i+(W\&(2^i-1))\) 的最大价值。
转移的时候我们枚举给 \(i-1\) 及以下的位多少容量,如果给了 \(k\),那么实际上下一位获得的就是 \(2k + W_{i-1}\),\(W_i\) 表示 \(W\) 的第 \(i-1\) 位。于是直接从 \(dp[i-1][2k+W_{i-1}]+f[i][j-k]\) 转移就可以了。
这个方法妙就妙在,发现我们不容易直接合并出 \(W\) 的限制,但是发现如果要合并出 \(W\),需要知道的是对于每一个 \(i\),某个在那一维上的容量 \(j\cdot 2^i\) 加上关于 \(W\) 在后面的位的情况,而这个东西可以进一步下去求。
#include<bits/stdc++.h>
#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back
template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}
typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
}
const int N = 100 + 7;
const int M = 31 + 3;
int n, w;
int siz[M], dp[M][N * 10];
pii v[M][N];
inline void work() {
memset(dp, 0, sizeof(dp));
for (int k = 0; k <= 31; ++k) {
int len = siz[k], mm = 10 * n;
for (int i = 1; i <= len; ++i)
for (int j = mm; j >= v[k][i].fi; --j)
smax(dp[k][j], dp[k][j - v[k][i].fi] + v[k][i].se);
if (k == 0) continue;
for (int i = mm; ~i; --i)
for (int j = 0; j <= i; ++j) smax(dp[k][i], dp[k][i - j] + dp[k - 1][std::min(mm, (j << 1) + ((w >> (k - 1)) & 1))]);
}
printf("%d\n", dp[31][0]);
}
inline void init() {
memset(siz, 0, sizeof(siz));
for (int i = 1; i <= n; ++i) {
int c, a, b = 0;
read(a), read(c);
while (!(a & 1)) a >>= 1, ++b;
v[b][++siz[b]] = pii(a, c);
}
}
int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
while (read(n), read(w), ~n && ~w) {
init();
work();
}
fclose(stdin), fclose(stdout);
return 0;
}
bzoj1190 [HNOI2007]梦幻岛宝珠 背包的更多相关文章
- BZOJ 1190 [HNOI2007]梦幻岛宝珠(背包)
1190: [HNOI2007]梦幻岛宝珠 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1385 Solved: 798[Submit][Stat ...
- 【题解】 bzoj1190: [HNOI2007]梦幻岛宝珠 (动态规划)
bzoj1190,懒得复制,戳我戳我 Solution: 这道题其实是一个背包(分组背包),但是由于数字比较大,就要重新构造dp式子.啃了三天才懂. \(dp[i][j]\)表示背包容积为\(j*2^ ...
- [HNOI2007]梦幻岛宝珠(背包)
给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值.数据范围:N<=100;W<=2^30,并且保证每颗宝石的重量符 ...
- bzoj1190 [HNOI2007]梦幻岛宝珠
传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1190 [题解] 首先,我们把所有物品都分解成$a\times 2^b$的形式,然后把物品按 ...
- bzoj1190 [HNOI2007]梦幻岛宝珠 动态规划
给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值.数据范围:N<=100;W<=2^30,并且保证每颗宝石的重量符 ...
- 【BZOJ1190】[HNOI2007]梦幻岛宝珠 分层背包DP
[BZOJ1190][HNOI2007]梦幻岛宝珠 Description 给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值. ...
- [BZOJ 1190][HNOI2007]梦幻岛宝珠
1190: [HNOI2007]梦幻岛宝珠 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1057 Solved: 611[Submit][Stat ...
- luogu 3188 [HNOI2007]梦幻岛宝珠
LINK:梦幻岛宝珠 时隔多日 我再次挑战这道题.还是以失败告终. 我觉得这一道背包真的有点难度 这是一个数量较少 但是价值和体积较大的背包. 通常的01背包 要不就是体积小 要么是价值小 但这道题给 ...
- BZOJ.1190.[HNOI2007]梦幻岛宝珠(分层背包DP)
题目链接 把重量表示为\(a\times2^b\)的形式,然后按\(b\)排序. 从高到低枚举每一位,\(f[i]\)表示当前位容量为\(i\)时的最大价值(容量即\(a\times2^{bit}\) ...
随机推荐
- C# windows窗口应用程序切换主界面的显示内容
不知道说清楚没有?就是我的窗口分为两部分,左边,控制部分,由一些按钮组成右边,显示部分,由些控件(如下拉,文本等等组成) 左边的每个按钮对应显示部分的页面,也就是说,左边换一个按钮点,那么右边就显示其 ...
- 学习日记3、投机取巧使两个表的数据同时在一个treeGrid中显示
不多说了直接上代码, $('#List').treegrid({ url: '@Url.Action("GetList")', width: $(window).width() - ...
- C# get和set
Day1:知识点 1.封装 自己的理解: 可复用,低耦合.就是拿过来就用 只需要关注名称,返回值,参数及参数类型,不需要知道里面怎么实现的. 字段封装的快捷键 (ctrl+r+e) 将光标放在将要封 ...
- Note:目录2
ylbtech-Note:目录2 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http://ylbtech ...
- 基于docker registry镜像安装私服docker hub
采用docker registry镜像安装docker私服,通过https://hub.docker.com/_/registry链接搜索registry镜像 1.输入命令:docker pull r ...
- C#=>递归反转栈
原理,递归反转栈 using System; using System.Collections.Generic; using System.Linq; using System.Threading.T ...
- 《JAVA设计模式》之工厂方法模式 (Factory)
在阎宏博士的<JAVA与模式>一书中开头是这样描述工厂方法模式的: 工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymor ...
- Java实现红黑树
转自:http://www.cnblogs.com/skywang12345/p/3624343.html 红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉 ...
- POJ-1679.The Unique MST.(Prim求次小生成树)
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 39561 Accepted: 14444 ...
- css 绘制checkbox,radio
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...