51Nod1306 高楼和棋子 动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1306.html
题目传送门 - 51Nod1306
题意
有个N层的高楼和若干个棋子,所有的棋子都是一样的。棋子从楼的某层E扔到地上不会碎(0 <= E <= N),但从比这个楼层高的地方扔到地上都会碎。给出楼的高度N,以及棋子的数量M,你来找出这个E(0 <= E <= N),问最坏情况下需要实验多少次才能计算出准确的E(如果棋子摔碎了,就不能继续用这个棋子进行测试了)。
1 <= N <= 10^18, 1 <= M <= 64
题解
由于本题的原题目背景中的棋子是“鹰蛋”,而蛋比棋子说起来方便,所以下文中都用蛋描述。
注意一下:一个蛋如果没有碎的话,还可以继续用!
我一开始zz了,写个基于二分原理的假做法。wa了好久并下载了一组数据然后以为数据出锅然后百度一下才反应过来。
我们考虑定义 $dp[i][j]$ 表示使用 $i$ 个蛋,抛 $j$ 次,能够确定的楼层总数。
我们有 $dp[i][j]=dp[i][j-1]+dp[i-1][j-1]+1$ 。为什么是这个式子?我们分三种情况论述:
1. 首先可以确定当前位置。 对于当前dp值的贡献:1
2. 如果蛋没碎,那么显然这个位置以下的全部都不会碎。我们要用 $i$ 个蛋抛 $j-1$ 次来确定这个位置以上能确定的楼层数,即 $dp[i][j-1]$ 。
3. 如果蛋碎了,那么显然这个位置以上的全部都会碎。我们要用剩余的 $i-1$ 个但抛 $j-1$ 次来确定这个位置以下能确定的楼层数,即 $dp[i-1][j-1]$ 。
由于当 $m\leq 2$ 的时候,抛的次数可能非常多,我们把它特判掉。
当 $m\leq 3$ 的时候,抛的次数很少了。
我们可以 $dp$ 预处理出来,最后 lower_bound 以下就可以了。由于存在很多无用的状态(dp值过大),所以我们可以用 vector 来只存一下有用状态。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL INF=1000000000000000001LL,N=2e6;
int T;
LL n,m;
vector <LL> dp[70];
int main(){
scanf("%d",&T);
dp[0].clear();
for (int i=0;i<=N;i++)
dp[0].push_back(0);
for (int i=1;i<=64;i++){
dp[i].clear();
dp[i].push_back(0);
for (int j=1;j<=N&&dp[i][j-1]<INF;j++)
dp[i].push_back(min(dp[i][j-1]+dp[i-1][j-1]+1,INF));
}
while (T--){
scanf("%lld%lld",&n,&m);
if (m==1)
printf("%lld\n",n);
else if (m==2){
n<<=1;
LL ans=sqrt(n);
if (ans*(ans+1)<n)
ans++;
printf("%lld\n",ans);
}
else
printf("%d\n",lower_bound(dp[m].begin(),dp[m].end(),n)-dp[m].begin());
}
return 0;
}
51Nod1306 高楼和棋子 动态规划的更多相关文章
- 【BZOJ3294】放棋子(动态规划,容斥,组合数学)
[BZOJ3294]放棋子(动态规划,容斥,组合数学) 题面 BZOJ 洛谷 题解 如果某一行某一列被某一种颜色给占了,那么在考虑其他行的时候可以直接把这些行和这些列给丢掉. 那么我们就可以写出一个\ ...
- BZOJ3294 CQOI2011放棋子(动态规划)
可以看做棋子放在某个位置后该种颜色就占领了那一行一列.行列间彼此没有区别. 于是可以设f[i][j][k]表示前k种棋子占领了i行j列的方案数.转移时枚举第k种棋子占领几行几列.注意行列间是有序的,要 ...
- [题解+总结]动态规划大合集II
1.前言 大合集总共14道题,出自江哥之手(这就没什么好戏了),做得让人花枝乱颤.虽说大部分是NOIP难度,也有简单的几道题目,但是还是做的很辛苦,有几道题几乎没思路,下面一道道边看边分析一下. 2. ...
- hdu 1087 动态规划之最长上升子序列
http://acm.hdu.edu.cn/showproblem.php?pid=1087 Online Judge Online Exercise Online Teaching Online C ...
- Google面试题之100层仍两个棋子
一道Google面试题,题目如下:"有一个100层高的大厦,你手中有两个相同的玻璃围棋子.从这个大厦的某一层扔下围棋子就会碎,用你手中的这两个玻璃围棋子,找出一个最优的策略,来得知那个临界层 ...
- 动态规划——线性dp
我们在解决一些线性区间上的最优化问题的时候,往往也能够利用到动态规划的思想,这种问题可以叫做线性dp.在这篇文章中,我们将讨论有关线性dp的一些问题. 在有关线性dp问题中,有着几个比较经典而基础的模 ...
- CJOJ 1087 【NOIP2010】乌龟棋 / Luogu 1541 乌龟棋(动态规划)
CJOJ 1087 [NOIP2010]乌龟棋 / Luogu 1541 乌龟棋(动态规划) Description 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 乌龟棋的棋盘是一行N个格子,每个 ...
- [NOIP复习]第三章:动态规划
一.背包问题 最基础的一类动规问题.相似之处在于给n个物品或无穷多物品或不同种类的物品,每种物品仅仅有一个或若干个,给一个背包装入这些物品,要求在不超出背包容量的范围内,使得获得的价值或占用体积尽可能 ...
- 【BZOJ1801】【AHOI2009】中国象棋(动态规划)
[BZOJ1801][AHOI2009]中国象棋(动态规划) 题面 题目描述 这次小可可想解决的难题和中国象棋有关,在一个N行M列的棋盘上,让你放若干个炮(可以是0个),使得没有一个炮可以攻击到另一个 ...
随机推荐
- CANopen--Copley驱动器 ACJ-055-18 过程数据PDO的断电保存方法
Copley CANopen 系列驱动器中,均保存有默认的 PDO 设置, 如下图所示 实际使用中,往往需要修改默认的 PDO 配置,以映射不同模式或功能下的 PDO 对象,但由于 PDO 配置无法存 ...
- 如何在同一台电脑上使用两个github账户(亲测有效)
1 前言 由于有两个github账号,要在同一台电脑上同步代码,需要给每一个账号添加一个SSH public key,此时推送时git push origin,不知道是哪个账号的远程仓库名称,所以需要 ...
- [MySQL]多表关联查询技巧
示例表A: author_id author_name 1 Kimmy 2 Abel 3 Bill 4 Berton 示例表B: book_id author_id start_date end_da ...
- VUE 数据请求和响应(axios)
1. 概述 1.1 简介 axios是一个基于Promise(本机支持ES6 Promise实现) 的HTTP库,用于浏览器和 nodejs 的 HTTP 客户端.具有以下特征: 从浏览器中创建 XM ...
- python-时间模块,random、os、sys、shutil、json和pickle模块
一.time与datetime模块 time模块: 时间戳:表示的是从1970年1月1日00:00:00开始按秒计算的偏移量,返回类型为float类型 格式化时间字符串(Format String) ...
- python基础教程(第二版)
开始学习python,根据Python基础教程,把里面相关的基础章节写成对应的.py文件 下面是github上的链接 python基础第1章基础 python基础第2章序列和元组 python基础第3 ...
- Confluence 6 升级你的许可证
如果你修改了你的许可证(例如为你的许可证增加了更多的用户),或者从 Cloud 中整合到你本地,你需要更新你的许可证. 希望更新你的额许可证: 进入 > 基本配置(General Config ...
- Android CTS Test
什么是CTS测试?了解这个问题前,我们先来搜索了解一遍“Google GMS 认证”.GMS全称为GoogleMobile Service,即谷歌移动服务.说白了GMS其实就是一系列谷歌的应用集合.谷 ...
- 10,关于在vs2017中的netcore项目使用BundlerMinifier 配置问题
查阅资料 https://github.com/madskristensen/BundlerMinifier/issues/230 今天下载了vs2017 rc 创建了个netcore的web项目,突 ...
- cf862d 交互式二分
/* 二分搜索出一个01段或10即可 先用n个0确定1的个数num 然后测试区间[l,mid]是否全是0或全是1 如果是,则l=mid,否则r=mid,直到l+1==r 然后再测试l是1还是r是1 如 ...