E - 梦幻岛宝珠

HYSBZ - 1190

这个题目我觉得很难,看题解都看了很久。

首先可以得到一个大概的思路就是分组,每一个数都可以分成 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背包 难的更多相关文章

  1. hdu2955(变形01背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955 分析:被抓概率可以转换成安全概率,Roy的安全概率大于1-P时都是安全的. 抢劫的金额为0时,肯 ...

  2. BZOJ 1190 梦幻岛宝珠(分组01背包)

    跑了7000ms... 这是个体积和价值都超大的背包.但是体积保证为a*2^b的(a<=10,b<=30)形式.且n<=100. 于是可以想到按b来分组.这样的话每组最多为a*n*2 ...

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

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

  4. BZOJ.1190.[HNOI2007]梦幻岛宝珠(分层背包DP)

    题目链接 把重量表示为\(a\times2^b\)的形式,然后按\(b\)排序. 从高到低枚举每一位,\(f[i]\)表示当前位容量为\(i\)时的最大价值(容量即\(a\times2^{bit}\) ...

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

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

  6. 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 ...

  7. UVA 562 Dividing coins --01背包的变形

    01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostre ...

  8. FZU 2214 Knapsack problem 01背包变形

    题目链接:Knapsack problem 大意:给出T组测试数据,每组给出n个物品和最大容量w.然后依次给出n个物品的价值和体积. 问,最多能盛的物品价值和是多少? 思路:01背包变形,因为w太大, ...

  9. codeforce Gym 101102A Coins (01背包变形)

    01背包变形,注意dp过程的时候就需要取膜,否则会出错. 代码如下: #include<iostream> #include<cstdio> #include<cstri ...

随机推荐

  1. Python财经数据接口包TuShare的使用

    安装TuShare 方式1:pip install tushare 方式2:访问https://pypi.python.org/pypi/tushare/下载安装 方式3:将源代码下载到本地pytho ...

  2. \r\n的意思

    \n是换行,英文是New line.\r是回车,英文是Carriage return. 1.换行符(line break),是一种计算机语言表达方式,它的作用是跳到下一个新行.在不同的语言中,代码也有 ...

  3. Ant概念

    Ant是基于Java的.可以跨平台的项目编译和生成工具.

  4. F 最大公约数和最小公倍数问题

    链接:https://ac.nowcoder.com/acm/contest/948/F来源:牛客网 输入2个正整数x0,y0(2<=x0<100000,2<=y0<=1000 ...

  5. C - 剪花布条 (KMP例题)

    一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?  Input输入中含有一些数据,分别是成对出现的花布条和 ...

  6. SQL入门,就这么简单

    随着时代的发展,人类活动产生的信息越来越多,大家常说,现在这个时代是大数据时代.在这样一个前提下,数据的存储成为我们必须要认真对待和研究的问题了.SQL(Structured Query Langua ...

  7. 2019CISCN华南线下两道web复现

    原帖地址 : https://xz.aliyun.com/t/5558 2019CISCN华南线下的两个简单 web 部分题目下载地址,有的不完整 : 点我点我 web 1 考点 : 无参函数的 RC ...

  8. 如何用Github钩子做自动部署

    最近机缘巧合的购置了域名和服务器,不用实在是浪费,再加上一直没有属于自己的个人网站,所以打算用hexo在服务器上玩一下,这样也就不用再纠结用Github pages还是Gitee pages了.当然, ...

  9. TensorFlow keras dropout层

    # 建立神经网络模型 model = keras.Sequential([ keras.layers.Flatten(input_shape=(28, 28)), # 将输入数据的形状进行修改成神经网 ...

  10. JS流程图解决方案GoJS

    GoJs简介 一个实现交互类图表(比如流程图,树图,关系图,力导图等等)的JS库 GoJS依赖于HTML5,所以请保证您的浏览器版本支持HTML5,当然还要加载这个库. 首先个人建议先下载官方实例的 ...