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

bzoj1190,懒得复制,戳我戳我

Solution:

  • 这道题其实是一个背包(分组背包),但是由于数字比较大,就要重新构造dp式子。啃了三天才懂。
  • \(dp[i][j]\)表示背包容积为\(j*2^i\)时的最大价值。
  • 首先,因为每一个物品一定是\(a*2^b\),我们可以按照\(b\)值先按照普通的分组背包去做,处理出每个\(b\)值所对应的\(dp\)值
  • 然后我们就是要把这些\(dp\)值累积起来,选择每组最大显然不合适,因为有可能每个组都剩下空间,剩余空间累加起来的空间还可以放物品,我们采用一下\(dp\)方法:

    \[dp[i][j] = max(dp[i][j] , dp[i][j-k]+dp[i-1][2*k+(w>>(i-1))])\]

  • \(i\)表示次方,\(j\)表示系数,\(k\)表示让出多少位置给\(i-1\)次方
  • 我们次方从小(\(1\))枚举到大(\(W\)最高位),系数从大枚举到小,要保证\(i\)位上的最大价值是没有更新过得,也就是不包括前面位置(\(2^{i-1}\))的物品,然后加上上一层(\(i-1\))最大放的空间的\(dp\)值(因为空间最大,所以存的价值一定是最大的)
  • 另外还有一个小细节,我们要把前面预处理每组背包时处理到\(2\)倍,因为后面更新时,会把\(i\)层腾的空间传给\(i-1\)层,例如\(i\)层腾了\(k\)空间,也就是\(i-1\)层多有\(2*k\)的空间,再加上\(W\)里面\(i-1\)位的空间就是\(i-1\)的空间最大
  • 最后输出\(dp[cnt][1]\),\(cnt\)是最高位,因为是最高位,所以最高位上一定是\(1\)
  • 看得还是比较迷糊的,戳这里,这个博客讲的挺详细的
  • 好像\(HNOI2007\)的题目都好毒瘤23333……

Code:

//It is coded by Ning_Mew on 4.19
#include<bits/stdc++.h>
#define LL long long
using namespace std;

const int maxn=107;

int n,cnt=0;
LL W,dp[maxn][2005],v,w;

int main(){
  while(1){
    memset(dp,0,sizeof(dp));
    scanf("%d%lld",&n,&W);
    if(n==-1)break;
    for(int i=1;i<=n;i++){
      scanf("%lld%lld",&w,&v);
      cnt=0;
      while(w%2==0)cnt++,w=w/2;
      //cout<<"w:"<<cnt<<‘ ‘<<w<<endl;
      for(int i=2000;i>=w;i--){
    dp[cnt][i]=max(dp[cnt][i],dp[cnt][i-w]+v);
      }
    }
    cnt=0;
    for(int i=30;i>=0;i--)if((W>>i)&1){cnt=i;break;}
    //cout<<"w:"<<cnt<<‘ ‘<<W<<endl;
    for(int i=1;i<=cnt;i++){
      for(int j=1000;j>=0;j--){
    for(int k=0;k<=j;k++){
      dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[i-1][2*k+((W>>(i-1))&1)]);
    }
      }
    }
    printf("%lld\n",dp[cnt][1]);
  }
  return 0;
}

原文地址:https://www.cnblogs.com/Ning-Mew/p/8886443.html

时间: 2024-10-16 17:22:52

【题解】 bzoj1190: [HNOI2007]梦幻岛宝珠 (动态规划)的相关文章

BZOJ 1190 HNOI2007 梦幻岛宝珠 动态规划

题目大意:01背包,其中weight<=2^30,但是每个weight都能写成a*2^b的形式,其中a<=10,b<=30 直接背包肯定TLE+MLE 考虑到每个weight都能写成a*2^b的形式,显然我们要按照b分层来进行背包 令f[i][j]表示有j*2^i+(w&(1<<i)-1)的空间时的最大价值 首先每层内部先做一个01背包 然后层与层之间再转移 从大到小枚举j 转移方程为f[i][j]=max{f[i][j],f[i][j-k]+f[i-1][min(k

【bzoj1190】[HNOI2007]梦幻岛宝珠 分层背包dp

题目描述 给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值.数据范围:N<=100;W<=2^30,并且保证每颗宝石的重量符合a*2^b(a<=10;b<=30) 输入 输入文件中包含多组数据.每组数据的格式如下:第一行是两个正整数n和W,1≤n≤100,1≤W≤2^30,分别表示宝石的数目和最多能带走的宝石重量.接下来的n行,每行有两个正整数weighti和valuei,1≤weighti≤2^30, 0≤

luogu3188/bzoj1190 梦幻岛宝珠 (分层背包dp)

他都告诉你能拆了 那就拆呗.把每个重量拆成$a*2^b$的形式 然后对于每个不同的b,先分开做30个背包 再设f[i][j]表示b<=i的物品中 容量为$ j*2^i+W\&((1<<(i-1))-1) $(就是这一位是j+W的前i-1位)的最大权值(这个容量没必要填满) 然后f[i][j]就可以从f[i-1][j*2+W的第i-1位]转移过来,再拿着这个去更新本层的其他容量 最后答案就是f[x][1],x是W的最高位1的位数 1 #include<bits/stdc++.

联赛之前的题表(已完成)汇总(可能有遗漏)

联赛之前的搞搞(其实是懒得分类) 博弈论 poj3537 poj1704 hdu5996两个插头 HDU1693 Eat the Trees COGS1283. [HNOI2004] 邮递员kdtree板子1941: [Sdoi2010]Hide and Seek旋转卡壳 pj2187凸包 cogs896 bzoj2829 信用卡凸包莫比乌斯反演基础 bzoj 4173 zhao gui lv bzoj 3529 mobiwus bzoj 4407 mobiwus bzoj 2818 mobiw

[题解]扫雷Mine

// 此博文为迁移而来,写于2014年11月4日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vrft.html 1088: [SCOI2005]扫雷Mine Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1730  Solved: 1028[Submit][Status] Description 相信大家都玩过扫雷的游戏.那是在一个n*m的矩阵里面有一些雷,要你根据

【高中组集体赛前热身赛】题解

(第一次给学弟们学妹写题解,可能有些地方我认为简单的可能没有仔细解释,所以导致没有讲清楚的一定要勤奋问百度,或者底下留言) [A-投掷硬币] 题解:基础DP(动态规划),dp[i][j]表示从第一个硬币开始翻,翻到第i个硬币的时候,翻到正面的有j个.那么dp[i][j]由dp[i-1][j-1](第i个是正面)和dp[i-1][j](第i个是反面)转移而来.所以由方程:dp[i][j]=dp[i-1][j]*(1.0-p[i])+dp[i-1][j-1]*p[i];当然j=0的话只能优dp[i-

动态规划(普及组)

入门篇:动态规划思想 动态规划向来都是OI竞赛生涯中的分水岭. 开篇杂谈 文章中有任何地方不懂可联系我$qq:2832853025$,退役前全天在线. 前置技能 DFS搜索. 记忆化搜索. 递推式.(高中必修五数学) 个人理解 照搬定义肯定不是传授知识的好办法,呢只是老师PPT上面爱放的东西. 在我个人的理解中,动态规划只是搜索的一种优化方法,但是并不可以优化所有的搜索.一般的来说,符合下面三条情况的搜索是可以转化为动态规划的思想来做的. 重叠子问题. 最优子结构. 子问题无后效性. 通俗的借用

vijos[1355]车队过桥问题

描述 现有N辆车要按顺序通过一个单向的小桥,由于小桥太窄,不能有两辆车并排通过.另外,由于小桥建造的时间已经很久,只能承受有限的重量,记为Max(吨).管理员将N辆车按初始的顺序分组,每次让一个组过桥,并且只有在一个组的车辆全部过桥后,下一组车辆才能上桥.每辆车的重量和最大速度是已知的,而每组车的过桥时间由该组中速度最慢的那辆车决定.请你帮管理员编一个程序,将这N辆车分组,使得全部车辆通过小桥的时间最短. 格式 输入格式 文件的第一行有3个数字,分别为Max(吨),Len(桥的长度,单位km),

Leetcode-70 Climbing Stairs

#70.    Climbing Stairs You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? 题解:这道题属于动态规划的题,类似于斐波那契数列,所以采用非递归的方式来解.当楼梯只有一级时,显然只有一种方法,即f(1