POJ 1243 解题报告

3 篇文章 0 订阅
2 篇文章 0 订阅

这是一道超小型dp题目,写的很快,索性写个报告

题目的意思是,一个猜价格的游戏。参与者有G次猜价格的机会,而且有L条命

每猜一次,用一次猜的机会,主持人会告诉你这个答案大了,小了还是猜中了。每次猜的价格高于真正的价格,丢一条命。G或者L用光而没有猜到,就输了。

问你,如果给定G和L,那么用一种保险的策略去猜,可以保证当这个价格在1到N之间时,肯定可以猜出正确价格。

写程序求这个N

G和L都不大于30,规模很小。


这题目一看基本就属于dp了,想一下怎么归纳到子问题就行了。

首先考虑集中情况

1.当L等于0的时候,那么一旦你猜多了,立刻就输了,所以只能1,2,3,4,这样往上猜,也就是输dp[i][0]一定等于i

2.当G和L相等时,也就是不用考虑L,你不可能出现G没用完L就用完的情况。那么有i次机会猜一个数,这个相当于过去说诸葛亮那个问十次大小猜数字的问题。dp[i][j] = 2^i - 1, 这个结论很简单

3.当以上两种情况都不符合时,这种需要稍微考虑一下。我们只考虑这游戏的第一个数字猜什么,后面的都是一样的,递归的道理。那么第一个数字猜什么呢,假设我才的是X,那么我们得保证,如果X比实际结果大,我失去了一个G和一个L,利用G-1和L-1,我可以把1~X-1猜的完。如果X比这个大的话,这个策略就有风险。所以,X = dp[g-1][l-1] + 1. 你利用G-1和L-1可以确保猜出的最大值再加1,就是你第一次猜的数字。那么如果你猜大了,损失了一个G和一个L,依然猜得出。如果猜小了,你还有G-1和L,所以还可以再覆盖dp[g-1][l]这么大的区域。这种情况时,dp[i][j] = dp[i-1][j-1] + 1 + dp[i-1][j],稍微想一下很容易想通的


这题是多case,所以预处理直接把所有值求出来,相当于打表。读哪个数据,直接输出哪个结果。0ms无压力

附代码

int dp[32][32];
int g,l;
int main()
{
	freopen("in.txt","r",stdin);
	MSET(dp);
	for (int i = 1; i <=30; i++)
	{
		for (int j = 0; j <= i; j++)
		{
			if (j == 0)
			{
				dp[i][j] = i;
			}
			else if (i == j)
			{
				dp[i][j] = pow((float)2,(float)i) - 1;
			}
			else 
			{
				dp[i][j] = dp[i-1][j-1] + dp[i-1][j] + 1;
			}
		}
	}
	int id = 0;
	int m;
	while (cin>>g>>l&&(g||l))
	{
		printf("Case %d: %d\n",++id,dp[g][l]);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值