传送门: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]梦幻岛宝珠的更多相关文章

  1. 【题解】 bzoj1190: [HNOI2007]梦幻岛宝珠 (动态规划)

    bzoj1190,懒得复制,戳我戳我 Solution: 这道题其实是一个背包(分组背包),但是由于数字比较大,就要重新构造dp式子.啃了三天才懂. \(dp[i][j]\)表示背包容积为\(j*2^ ...

  2. bzoj1190 [HNOI2007]梦幻岛宝珠 动态规划

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

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

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

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

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

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

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

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

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

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

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

  8. BZOJ1190[HNOI2007]梦幻岛宝石

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

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

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

随机推荐

  1. pygame学习笔记(6)——一个超级简单的游戏

    转载请注明:@小五义  http://www.cnblogs.com/xiaowuyi 学了这么长时间的Pygame,一直想写个游戏实战一下.看起来很简单的游戏,写其来怎么这么难.最初想写个俄罗斯方块 ...

  2. [细品java]ThreadLocal源码学习

    ThreadLocal是线程局部变量,其中保存了特定于该线程的值.每个线程都拥有一份独立的副本值,即每个线程修改变量值不影响其他线程该变量的副本值.这些特定于线程的值保存在Thread对象中,当线程终 ...

  3. robotium学习及整理

    一.                      Robotium 简介 Robotium是一款国外的Android自动化测试框架,主要针对Android平台的应用进行黑盒自动化测试,它提供了模拟各种手 ...

  4. how to know iframe is loaded in js

    how to know iframe is loaded in js ??? iframe & HTTPS & CORS https://iframe.xgqfrms.xyz/eapp ...

  5. NOI2017 退役记

    OI生涯最后一篇游记写点不开心的让大家开心一下 Day -2(7.16) 上午的模拟赛奥妙重重. 下午也没怎么改题,看了一些新题,发现都不会,都看了下题解,发现大部分没看懂,好慌. 发现板子还没怎么复 ...

  6. VS2010 重命名文件:源文件名和目标文件名相同 的解决方案

    想要在“”解决方案资源管理器“”中修改一个已经写好的文件的文件名,如图: 在改了几次后就出现了如图的问题: 然而在“解决方案资源管理器”中并没有看到,于是我打开了工程在磁盘中的位置文件夹: 意外发现了 ...

  7. 什么是 metadata (元数据)

    1. 什么是元数据 任何文件系统中的数据分为数据和元数据.数据是指普通文件中的实际数据,而元数据指用来描述一个文件的特征的系统数据,诸如访问权限.文件拥有者以及文件数据块的分布信息(inode...) ...

  8. 解题:JSOI 2007 重要的城市

    题面 考虑一个点$x$,如果某两个点$u,v$间的所有最短路都经过$x$,那么$x$肯定是重要的.这个题$n$比较小,所以我们直接跑floyd,在过程中记录 当发生松弛时,我们具体讨论: 如果这个长度 ...

  9. bug3 乱码问题

    出现乱码问题是因为各软件之间的编码方式不同导致 1.tomcat修改编码方法: 2.myeclipse中修改编码方式的方法: window----preference ----general----- ...

  10. D. Vitya and Strange Lesson Codeforces Round #430 (Div. 2)

    http://codeforces.com/contest/842/problem/D 树 二进制(路径,每个节点代表一位) #include <cstdio> #include < ...