#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1e4 + 5;
int f[4][N];
int main()
{
int n;
scanf("%d", &n);
//将摔手机次数初始化为楼层数
for (int i = 1; i <= 3; i ++ )
for (int j = 0; j <= n; j ++ )
f[i][j] = j;
for (int i = 2; i <= 3; i ++ )
for (int j = 1; j <= n; j ++ )
for (int k = 1; k <= j; k ++ )
f[i][j] = min(f[i][j], max(f[i-1][k-1], f[i][j-(k+1)+1])+1);
printf("%d", f[3][n]);
return 0;
}
请问一下,为什么要将摔手机次数初始化楼层数
因为要求的是最小值,所以一开始将数组初始化为一个极大值
如果有k楼的话,不采用任何策略, 一楼一楼摔,摔k次肯定能测出手机的耐摔程度,所以楼层数就相当与一个极大值
懂了懂了,谢谢啦:)
for (int i = 2; i <= 3; i )
for (int j = 1; j <= n; j )
for (int k = 1; k <= j; k ++ )
f[i][j] = min(f[i][j], max(f[i-1][k-1], f[i][j-(k+1)+1])+1);
请问,为什么要把每种情况都求出来,为什么不能只求f[3][n]=min(f[i][j], max(f[i-1][k-1], f[i][j-(k+1)+1])+1);
#include [HTML_REMOVED]
using namespace std;
const int maxn = 10010;
int f[maxn][4] = { 0 };
int main() {
int n;
scanf(“%d”, &n);
}
请问那个手机枚举为什么从2开始,我写的从1开始,为啥结果不对
%%%
这种题怎么想到的,看到后感觉很陌生,不看题解甚至正确的测试方法都没搞懂
为什么是f[4][N]呢
因为初始值就是方案数的最大值, 所以
f[i][j] = min(f[i][j], max(f[i - 1][k - 1], f[i][j - (k + 1) + 1]) + 1)
就是最优策略下最坏运气的最大方案数, 但是为什么会有运气这个说法呢, 一个手机本来应该在7楼摔坏, 是不是也有可能不在7楼摔坏,导致测试次数变多吗,请问最大值为什么会加上一个1呢,还有为啥i是从2开始枚举的呀
加1 是因为测试的次数加一了呀 i从二开始枚举是因为当你只有一个手机的时候你只能从下往上一层一层摔了,所以最坏情况就是 摔得次数等于层数
谢谢大佬解答!我太菜了qwq
大佬这个题属于什么类型的dp呢
牛啤,顶一下
懂了,这里要放弃之前固有的二分想法,把测量a1层到a2层等价到a1 + x 到a2 + x层上来
想问一下,怎么保证最后一定能测试出手机的耐摔指数呢,感觉楼层不用太高,40层,3个手机就不够用;我是按,二分的思想,最坏就是,20层摔坏了,10层摔坏了,5层摔坏了,手机没了,也没测试出来
二分法的摔法也是一种摔法,但不一定是最优的。
如果最后摔的只剩一部手机了,为了在最坏运气下测试出来,就只能从低到高一层层摔。
所以代码中所有的f[1][n] = n, n即楼层数
奥,原来是这样测试呀,谢谢讲解
TQL
一看就是y总的dp分析法,这篇题解很牛
牛的,我还是不会套y式dp分析法