E - 梦幻岛宝珠 HYSBZ - 1190 变形01背包 难
E - 梦幻岛宝珠
这个题目我觉得很难,看题解都看了很久。
首先可以得到一个大概的思路就是分组,每一个数都可以分成 a*2^b 所以把b相同的数都分成一个组。
在每一组内部进行01背包,这个操作比较简单。
比较难的是组与组之间进行转移。
定义 dp[i][j] 表示在第i层容量为 j*2^i 的最大价值。
那么怎么从第 i-1 层转移到第 i 层呢?
因为到dp[i][j] 到第 i 层的容量为 第 i 层本身的容量+之前总容量 所以就是 j*2^i+w&((1<<i)-1)
假设第 i 层只用了 (j-k)*2^i 这么多的容量,那么第(i-1)层还可以多用 k*2^i 这么多的容量。
那这样子怎么转移呢?
假设是从dp[i-1][x] 转移过来 就是说 i-1 层用了 x*2^(i-1) 的容量
因为到底 i 层一共有 j*2^i+w&((1<<i)-1) 的容量,第 i 层用了 (j-k)*2^i 的容量
所以 x*2^(i-1)=j*2^i+w&((1<<i)-1)-(j-k)*2^i
解出 x=2*k+(w>>(i-1)&1)
所以转移方程为 dp[i][j]=max(dp[i][j],dp[i-1][2*k+(w>>(i-1)&1)])
因为一共只有n个宝石,如果这n个宝石放在了同一组,而且 a*2^b 的a 都为10 这个第二维最大也只有10*n
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <algorithm>
#include <iostream>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = + ;
typedef long long ll;
int dp[][]; int main() {
int n, m;
while (scanf("%d%d", &n, &m) && n != - && m != -) {
memset(dp, , sizeof(dp));
for (int i = ; i <= n; i++) {
int w, val, a = ;
scanf("%d%d", &w, &val);
while (w % == ) w /= , a++;
for (int j = ; j >= w; j--) dp[a][j] = max(dp[a][j], dp[a][j - w] + val);
}
int w = m, up = ;
for (int i = w; i; i >>= ) up++; up--;
for (int i = ; i <= up; i++) {
for (int j = ; j >= ; j--) {
for (int k = ; k <= j; k++) {
dp[i][j] = max(dp[i][j], dp[i][j - k] + dp[i - ][min(, * k + ((w >> (i - )) & ))]);
}
}
}
printf("%d\n", dp[up][]);
}
return ;
}
E - 梦幻岛宝珠 HYSBZ - 1190 变形01背包 难的更多相关文章
- hdu2955(变形01背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955 分析:被抓概率可以转换成安全概率,Roy的安全概率大于1-P时都是安全的. 抢劫的金额为0时,肯 ...
- BZOJ 1190 梦幻岛宝珠(分组01背包)
跑了7000ms... 这是个体积和价值都超大的背包.但是体积保证为a*2^b的(a<=10,b<=30)形式.且n<=100. 于是可以想到按b来分组.这样的话每组最多为a*n*2 ...
- BZOJ 1190 [HNOI2007]梦幻岛宝珠(背包)
1190: [HNOI2007]梦幻岛宝珠 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1385 Solved: 798[Submit][Stat ...
- BZOJ.1190.[HNOI2007]梦幻岛宝珠(分层背包DP)
题目链接 把重量表示为\(a\times2^b\)的形式,然后按\(b\)排序. 从高到低枚举每一位,\(f[i]\)表示当前位容量为\(i\)时的最大价值(容量即\(a\times2^{bit}\) ...
- [BZOJ 1190][HNOI2007]梦幻岛宝珠
1190: [HNOI2007]梦幻岛宝珠 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1057 Solved: 611[Submit][Stat ...
- Codeforces 2016 ACM Amman Collegiate Programming Contest A. Coins(动态规划/01背包变形)
传送门 Description Hasan and Bahosain want to buy a new video game, they want to share the expenses. Ha ...
- UVA 562 Dividing coins --01背包的变形
01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostre ...
- FZU 2214 Knapsack problem 01背包变形
题目链接:Knapsack problem 大意:给出T组测试数据,每组给出n个物品和最大容量w.然后依次给出n个物品的价值和体积. 问,最多能盛的物品价值和是多少? 思路:01背包变形,因为w太大, ...
- codeforce Gym 101102A Coins (01背包变形)
01背包变形,注意dp过程的时候就需要取膜,否则会出错. 代码如下: #include<iostream> #include<cstdio> #include<cstri ...
随机推荐
- logback日志实战
<?xml version="1.0" encoding="UTF-8" ?> <!-- <configuration> < ...
- 微信小程序页面通信
目录 微信小程序页面通信 方式一:通过URL 方式二:通过全局变量 方式三:通过本地存储 方式四:通过路由栈 微信小程序页面通信 方式一:通过URL // A 页面 wx.navigateTo({ u ...
- [总结]最近公共祖先(倍增求LCA)
目录 一.定义 二.LCA的实现流程 1. 预处理 2. 计算LCA 三.例题 例1:P3379 [模板]最近公共祖先(LCA) 四.树上差分 1. 边差分 2. 点差分 3. 例题 一.定义 给定一 ...
- .NetCore程序在Linux上面部署的实现
我们知道.NetCore能够实现跨平台的根本就是内置Kestrel服务器实现请求处理和不同操作系统上反向代理的实现.在windows操作系统上IIS反向代理配置非常简单.但是Linux上就较为麻烦了. ...
- Python - 批量获取文件夹的大小输出为文件格式化保存
很多时候,查看一个文件夹下的每个文件大小可以轻易的做到,因为文件后面就是文件尺寸,但是如果需要查看一个文件夹下面所有的文件夹对应的尺寸,就发现需要把鼠标放到对应的文件夹上,稍等片刻才会出结果. 有时候 ...
- 图解Knative核心组件Serving基础设计
最近闲下来,打算把Knative的核心组件Serving给学习下,会继续采用k8s源码学习的方式,管中窥豹以小击大,学习serving的主要目标: 可观测性基础设施.自动伸缩.流量管理等核心组件的设计 ...
- 尝试用python开发一款图片压缩工具1:尝试 pillow库
开发目的 我经常使用图片.公众号文章发文也好,还是生活中要使用素材.图片是一种比文字更加直观的载体.但是图片更加占用带宽,很多软件都对图片有大小限制.图片太大也会影响加载速度.我试过几款图片压缩工具, ...
- 必须先理解的RocketMQ入门手册,才能再次深入解读
RocketMQ入门手册 RocketMQ是一个分布式.队列模型的开源消息中间件,前身是MetaQ,是阿里研发的一个队列模型的消息中间件,后开源给apache基金会成为了apache的顶级开源项目,具 ...
- kubernetes删除pod,pod一直处于Terminating状态
删除pod,pod一直处于Terminating状态 [root@yxz-cluster01 deploy_yaml]# kubectl get pod -n yunanbao NAME READY ...
- 使用Reactor响应式编程
介绍 响应式编程 响应式编程不同于我们熟悉的命令式编程,我们熟悉的命令式编程即代码就是一行接一行的指令,按照它们的顺序一次一条地出现.一个任务被执行,程序就需要等到它执行完了,才能执行下一个任务.每一 ...