bzoj1190 [HNOI2007]梦幻岛宝珠
传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1190
【题解】
首先,我们把所有物品都分解成$a\times 2^b$的形式,然后把物品按照$b$分组;
我们按$b$从高到低考虑。$f(i,j)$表示考虑到$2^i$,当前还剩余$j\times 2^i$的空间,所能取到的最大值。
每层先从上一层传递$f$数组,然后再更新。每次就是一个背包转移了。
考虑这个$j$可能随着$b$减小越来越大,我们需要优化。
对于每一层的物品,最多只能表示成$na\times 2^b$的形式,即最多$1000 \times 2^b$。
所以对于上一层传下来的值,如果它乘了2之后大于1000,实际上这些多于1000的部分是没有用的,我们可以直接舍弃!
这样的话就能保证复杂度了!
# include <vector>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; const int M = 5e5 + ;
const int mod = 1e9 + ; int n, W; vector<int> w[], v[];
ll f[][];
int to[]; bool Main() {
cin >> n >> W;
if(n == - && W == -) return ;
for (int j=; j<=; ++j) {
w[j].clear(), v[j].clear(), to[j] = ;
for (int i=; i<=; ++i) f[j][i] = ;
}
for (int j=; j<=n; ++j) {
int ww, vv;
cin >> ww >> vv;
for (int i=; ~i; --i) {
if(ww % ( << i) == ) {
w[i].push_back(ww / ( << i));
v[i].push_back(vv);
break;
}
}
} for (int j=, curW=; ~j; --j) {
bool flag = ;
to[j] = to[j+] * ;
if(W & (<<j)) flag = , to[j] ++; if(to[j] <= ) {
for (int i=; i<=to[j]; ++i)
if(flag == ) {
if(i% == ) f[j][i] = f[j+][i/];
} else if(i% == ) f[j][i] = f[j+][i/];
} else {
for (int i=; i<=; ++i)
if(flag == ) {
if(i% == ) f[j][i] = f[j+][i/];
} else if(i% == ) f[j][i] = f[j+][i/];
for (int i=; i<=to[j+]; ++i)
f[j][] = max(f[j][], f[j+][i]);
to[j] = ;
} for (int k=, kto = w[j].size(); k<kto; ++k) {
for (int i=; i<=to[j]; ++i) {
int tw = w[j][k], tv = v[j][k];
if(i - tw >= ) f[j][i-tw] = max(f[j][i-tw], f[j][i]+tv);
}
} } ll ans = ;
for (int i=to[]; ~i; --i) ans = max(ans, f[][i]);
cout << ans << endl;
return ;
} int main() {
while(Main());
return ;
}
bzoj1190 [HNOI2007]梦幻岛宝珠的更多相关文章
- 【题解】 bzoj1190: [HNOI2007]梦幻岛宝珠 (动态规划)
bzoj1190,懒得复制,戳我戳我 Solution: 这道题其实是一个背包(分组背包),但是由于数字比较大,就要重新构造dp式子.啃了三天才懂. \(dp[i][j]\)表示背包容积为\(j*2^ ...
- bzoj1190 [HNOI2007]梦幻岛宝珠 动态规划
给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值.数据范围:N<=100;W<=2^30,并且保证每颗宝石的重量符 ...
- bzoj1190 [HNOI2007]梦幻岛宝珠 背包
题目 https://lydsy.com/JudgeOnline/problem.php?id=1190 题解 好神仙的一道题啊. 既然 \(w_i = a_i\cdot 2^{b_i}\),那么不妨 ...
- 【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 ...
- BZOJ 1190 [HNOI2007]梦幻岛宝珠(背包)
1190: [HNOI2007]梦幻岛宝珠 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1385 Solved: 798[Submit][Stat ...
- luogu 3188 [HNOI2007]梦幻岛宝珠
LINK:梦幻岛宝珠 时隔多日 我再次挑战这道题.还是以失败告终. 我觉得这一道背包真的有点难度 这是一个数量较少 但是价值和体积较大的背包. 通常的01背包 要不就是体积小 要么是价值小 但这道题给 ...
- BZOJ1190[HNOI2007]梦幻岛宝石
Description 给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值.数据范围:N<=100;W<=2^30, ...
- 1190: [HNOI2007]梦幻岛宝珠 - BZOJ
Description 给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值. 数据范围:N<=100;W<=2^30 ...
随机推荐
- jquery 取消全选和全选功能 不全选
代码如下 function ckSelectAll() { if ($('#ckSelectAll').is(':checked') == true) { $("INPUT[name='ch ...
- 6/12 sprint2 看板和燃尽图的更新
- redis批量删除key 命令
redis-cli -n 数据库编号 -a 密码 keys "过滤条件" | xargs redis-cli -n 数据库编号 -a 密码 del Demo: redis-cli ...
- PHP数据库常用常量笔记
参考:http://php.net/manual/zh/pdo.constants.php Warning 自 PHP 5.1 起,开始使用类常量.以前的版本使用类似 PDO_PARAM_BOOL 这 ...
- HTML标签参考手册
按字母顺序排列 New : HTML5 中的新标签. 标签 描述 <!--...--> 定义注释. <!DOCTYPE> 定义文档类型. <a> 定义锚. < ...
- 二叉树 Java 实现 前序遍历 中序遍历 后序遍历 层级遍历 获取叶节点 宽度 ,高度,队列实现二叉树遍历 求二叉树的最大距离
数据结构中一直对二叉树不是很了解,今天趁着这个时间整理一下 许多实际问题抽象出来的数据结构往往是二叉树的形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显 ...
- hibernate关联关系
hibernate是一个强大的ORM框架,为了使用面向对象的方式管理数据库,hibernate提供了4中关系设置: 1.一对一 (one-to-one) 2.一对多 (one-to-many) 3.多 ...
- iOS 字符串NSString 的一些常用方法
一.字符串创建 1. NSString *str1 = [NSString new]; 2. NSString *str2 = @"字符串内容"; 二.字符串拼接 1. NSStr ...
- Ubuntu 12.04下LAMP环境搭建实录
方法一: 用tasksel可以方便安装dns server, lamp, kubuntu desktop, ubuntu desktop, xubuntu之类的软件包.这个软件在ubuntu serv ...
- BZOJ3162 独钓寒江雪(哈希+树形dp)
数独立集显然是可以树形dp的,问题在于本质不同. 假设已经给树确立了一个根并且找到了所有等效(注意是等效而不是同构)子树,那么对转移稍加修改使用隔板法就行了. 关键在于找等效子树.首先将树的重心(若有 ...