题解 POJ One Person

Given G guesses and L lifelines, find the largest N such that a winning strategy exists for prices between 1 and N in the one-person version of 'The Price is Right'. The strategy involves binary-like guessing based on feedback." 117082403,8346914,Vue按钮组件详解与应用,"['前端开发', 'Vue', '组件库', '按钮设计']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

O n e   P e r s o n \color{blue}{One\ Person} One Person

Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 2752Accepted: 1779

D e s c r i p t i o n \color{blue}{Description} Description

In the game show “The Price is Right”, a number of players (typically 4) compete to get on stage by guessing the price of an item. The winner is the person whose guess is the closest one not exceeding the actual price. Because of the popularity of the one-person game show “Who Wants to be a Millionaire”,the American Contest Management (ACM) would like to introduce a one-person version of the “The Price is Right”. In this version, each contestant is allowed G (1 <= G <= 30) guesses and L (0 <= L <= 30)lifelines. The contestant makes a number of guesses for the actual price. After each guess, the contestant is told whether it is correct, too low, or too high. If the guess is correct, the contestant wins. Otherwise,he uses up a guess. Additionally, if his guess is too high, a lifeline is also lost. The contestant loses when all his guesses are used up or if his guess is too high and he has no lifelines left. All prices are positive integers.

It turns out that for a particular pair of values for G and L, it is possible to obtain a guessing strategy such that if the price is between 1 and N (inclusive) for some N, then the player can guarantee a win.The ACM does not want every contestant to win, so it must ensure that the actual price exceeds N.At the same time, it does not want the game to be too diffcult or there will not be enough winners to attract audience. Thus, it wishes to adjust the values of G and L depending on the actual price. To help them decide the correct values of G and L, the ACM has asked you to solve the following problem.Given G and L, what is the largest value of N such that there is a strategy to win as long as the price is between 1 and N (inclusive)?
Input

I n p u t \color{blue}{Input} Input

The input consists of a number of cases. Each case is specified by one line containing two integers G and L, separated by one space. The end of input is specified by a line in which G = L = 0.

O u t p u t \color{blue}{Output} Output

For each case, print a line of the form:
Case c: N
where c is the case number (starting from 1) and N is the number computed.

S a m p l e   I n p u t \color{blue}{Sample\ Input} Sample Input

3 0
3 1
10 5
7 7
0 0

S a m p l e   O u t p u t \color{blue}{Sample\ Output} Sample Output

Case 1: 3
Case 2: 6
Case 3: 847
Case 4: 127

S o u r c e \color{blue}{Source} Source

East Central North America 2002


d p ( G , L ) dp(G,L) dp(G,L)为有 G G G次机会, L L L点生命值时最多可猜到多少个数字(注意此处的描述猜数字我们都知道是要用二分法来猜。)

首先,要考察 G G G L L L间的大小关系:

L = 0 L=0 L=0,即一次都不可以猜高了,那么保险能猜到的方案就只有 1 、 2 、 3 、 4... 1、2、3、4... 1234...的一个一个往上猜,那么最多能猜到的数字个数也就是 G G G

L &gt; G L&gt;G L>G,即可以猜高的次数比较多。可事实上,每次猜测都要耗费一点 G G G,那么多出来的生命值也就没什么意义了,所以这种情况与 L = G L=G L=G相同,即 d p ( G , G ) dp(G,G) dp(G,G)

L ⩽ G L\leqslant G LG,那么,就要继续分类考虑。首先进行一次猜测(假设猜的是 k k k),那么可能得到以下三种情况之一:

  1. 猜低了。也就是说明正确答案大于 k k k(此处可脑补一条以 k k k为原点的数轴辅助理解),那么接下来的猜测就要相对于 k k k往前(以数轴正方向为前),此时剩余 G − 1 G-1 G1点机会, L L L点生命,也就是说可以再向前猜出 d p ( G − 1 , L ) dp(G-1,L) dp(G1,L)个数字。
  2. 猜高了。也就是说正确答案小于k,那么接下来就要相对于 k k k向后猜,同理,可以再向后猜出 d p ( G − 1 , L − 1 ) dp(G-1,L-1) dp(G1,L1)个数字。
  3. 恰好猜到~

总结下,即当 L &lt; = G L&lt;=G L<=G时, d p ( G , L ) = d p ( G − 1 , L ) + d p ( G − 1 , L − 1 ) + 1 dp(G,L)=dp(G-1,L)+dp(G-1,L-1)+1 dp(G,L)=dp(G1,L)+dp(G1,L1)+1

代码实现如下:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int MAXN=35;
int Case=0;
int dp[MAXN][MAXN];

int dfs(int g,int l)
{
	if(g==0) return 0;
	if(l==0) return g;
	if(dp[g][l]) return dp[g][l];
	dp[g][l]=dfs(g-1,l)+dfs(g-1,l-1)+1;
	return dp[g][l]; 
}

int main()
{
	int g,l;
	while(scanf("%d%d",&g,&l))
	{
		if(g==0&&l==0) break;
		printf("Case %d: %d\n",++Case,dfs(g,l));
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值