题解 P3188 【[HNOI2007]梦幻岛宝珠】 DP
2018-01-15 09:01
387 查看
~By Bartholomew~
其实,这道题目,评价:1.难度: @@@@@
2.思维难度: @@@
3.细节难度: @@@@@
对于这道题目,我们发现其实就是普通的 01 背包,但是数据 十分的大!
那么我们可以对于 v = a×2b;的 b 相同的物品做一次 dp
那么就是* f[i][j] * 表示体积为 (j×2i) 的体积 只收纳 k×2i 的物品的最大值
那么最后就是 怎么合并是关键部分!
如果我们假设 f[i][j] 现在表示
表示20 ~~ 2i组内, 容量为 j×2i+(w&((1<< i)−1)) 时的最大价值
也就是f[i,j]表示体积为j× 2i再加上W**二进制第i位以下的体积**最多可以获得多少价值
那么 我们的 答案其实就是 dp[len][1] , len指的是 最大的i 是 2i 小于等于 m 的值!
那么 我们就是考虑转移 从 f[i−1][...] 开始转移!
转移方程:
f[i,j]=max(f[i,j],f[i,j−k]+f[i−1],min(k∗2+e[i−1],d[i−1])]);
其中好多是小细节部分:
for(int j=w[i];j>=0;--j) for(int k=0;k<=j;k++) // 这下面的f[i][j-k] (用"*"标注的)1其实并没有变动,因为是反着来求的,所以还是表示 单单是 2^i 的物品,大家可以写一下式子,就明白了! f[i][j] = getmax(f[i][j] , **f[i][j-k]** + f[i-1][min(w[i-1],(k<<1)|(m>>(i-1)&1))]);
贴上代码 , 有明显的小错误的哦!
#pragma GCC optimize(3) #include <iostream> #include <stdio.h> #include <algorithm> #include <cstring> #include <queue> #include <vector> #define N 200005 #define INF 0x3f3f3f3f using namespace std; int n,m,len,x,y,f[35][1150],w[35]; inline int read() { int x=0; char c=getchar(); while(c<'0'||c>'9'){c=getchar();} while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();} return x; } vector<int> G[35],V[35]; inline int getmax(int x,int y){return (x>y)?x:y; } inline void init() { len = 0; memset(G,0,sizeof G); memset(V,0,sizeof V); memset(w,0,sizeof w); memset(f,0,sizeof f); } int main(int argc,char const* argv[]) { while(~scanf("%d%d",&n,&m) && n!=-1) { init(); for(int i=1;i<=n;++i) { x = read(); int j = 0; while(!(x&1)) { x>>=1; j++; } G[j].push_back(x); w[j] += x; len = getmax( len , j); scanf("%d",&y); V[j].push_back(y); } for(int i=0;i<=len;i++) for(int j=0;j<(int)G[i].size();++j) for(int k=w[i];k>=G[i][j];k--) f[i][k] = getmax(f[i][k],f[i][k-G[i][j]]+V[i][j]); while(m>>len) len++; len--; for(int i=1;i<=len;i++) { w[i] += (w[i-1]+1)/2; for(int j=w[i];j>=0;--j) for(int k=0;k<=j;k++) f[i][j] = getmax(f[i][j] , f[i][j-k] + f[i-1][min(w[i-1],(k<<1)|(m>>(i-1)&1))]); } printf("%d\n",f[len][1]); } return main(); }
相关文章推荐
- 【BZOJ1190】[HNOI2007]梦幻岛宝珠 分层背包DP
- [数位DP] BZOJ1190. [HNOI2007]梦幻岛宝珠
- bzoj1190 [HNOI2007]梦幻岛宝珠 ( 二进制分组优化背包DP)
- BZOJ 1190: [HNOI2007]梦幻岛宝珠 背包DP
- 【bzoj1190】[HNOI2007]梦幻岛宝珠 分层背包dp
- [DP]BZOJ 1190——[HNOI2007]梦幻岛宝珠 动态规划]
- [bzoj1190][HNOI2007]梦幻岛宝珠 分组背包
- BZOJ 1190: [HNOI2007]梦幻岛宝珠
- BZOJ 1190 [HNOI2007]梦幻岛宝珠
- BZOJ 1190 HNOI2007 梦幻岛宝珠 动态规划
- 1190: [HNOI2007]梦幻岛宝珠 - BZOJ
- [BZOJ 1190][HNOI2007]梦幻岛宝珠
- 分层背包 [HNOI2007]梦幻岛宝珠
- 1190: [HNOI2007]梦幻岛宝珠
- BZOJ 1187 HNOI 2007 神奇游乐园 插头DP
- bzoj 1187: [HNOI2007]神奇游乐园 插头dp
- [HNOI2007][bzoj1187] 神奇游乐园 [插头dp]
- bzoj 1187: [HNOI2007]神奇游乐园 插头dp
- BZOJ 1187 HNOI2007 神奇游乐园 插头DP
- [BZOJ]1187: [HNOI2007]神奇游乐园 插头DP