蓝桥杯2018第九届C语言B组省赛习题题解——习题D.测试次数*(经典递推)

每日刷题(四十六)

蓝桥杯第九届C语言B组省赛习题

习题D:测试次数

在这里插入图片描述
每次都感觉蓝桥杯出的题目都特别有趣,尤其是背景信息

这个题可以用递推,不能考虑二分法!

我们知道如果只给你一部手机测,也就是说只有一次机会,摔坏了就没办法测了,我们就会采取从第一层逐层往上测,那么最坏的运气就是你手机摔坏的层数,一部手机的情况下就不需要考虑最佳策略了,因为考虑不了

如果给你两部手机测,那么你就有两次机会。我们知道dp[i][2] = d[[i -1][2] + 1,手机测试次数最大值所满足的公式。我解释一下,坏运气就是你要一直测下去,增加测试次数,所以第i层的测试次数就是第i - 1层的测试数据 + 1,在第i层摔没摔坏我们不需要管,而d[i-1][2] + 1中下标为何是2呢,如果你再第i - 1层摔坏了,那你还会往上测吗?

接着考虑最佳策略:
最高楼为j层
在第k层摔:
1)如果摔坏了,则d[k - 1][2 - 1] + 1
2)如果没坏,则继续往上走d[j - k][2] + 1
我们就是要取两种情况中最大次数t,然后再取min(t, d[j][2])

这就是大致思路

详细C代码如下:

#include<stdio.h>

int Max(int a, int b)
{
	return a > b ? a : b;
}

int Min(int a, int b)
{
	return a < b ? a : b;
}

int main()
{
	int dp[1001][3] = {0};
	int i, j;
	for(i = 1; i < 1001; i++)
		dp[i][1] = i;			//只有一部手机时从下往上测试最坏测试次数
	int k; 
	for(i = 2; i <= 3; i++)
	{
		for(j = 1; j <= 1000; j++)
		{
			dp[j][i] = 1 + dp[j - 1][i];	//dp[i][j]的最大值总是满足dp[i][j]= dp[i-1][j]+1 
			for(k = 2; k <= j; k++)			//因为不知道手机的耐摔指数,一切都从二层开始 
			{
				dp[j][i] = Min(dp[j][i], 1 + Max(dp[k - 1][i - 1], dp[j - k][i])); 
			}		//好坏情况中最大值是最坏运气与dp[i][j]中的最小值便是最佳策略 
		}			//如果在第k层手机摔坏了,则dp[k - 1][i - 1]
					//如果在第k层手机没坏,则dp[j - k][i]
	}
	printf("%d\n", dp[1000][3]);
	return 0;
}

运行结果如下:
在这里插入图片描述
所以最坏运气下采取最佳策略需要测19次

如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持,下期更精彩!!!

发布了99 篇原创文章 · 获赞 16 · 访问量 5905

猜你喜欢

转载自blog.csdn.net/qq_44631615/article/details/105162332