poj1243 猜数最大 dp

One Person
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 2122 Accepted: 1426

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

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. 

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. 

Sample Input

3 0
3 1
10 5
7 7
0 0

Sample Output

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

有G次机会,L次猜高机会,问最大能猜到的数字是多大

dp[i][j]表示有i次机会,j次猜高机会能猜到最大数字

首先我们要分析一次G和L的关系,

如果L=0,那么我们只能从1枚举到G,因此dp[G][0]=G

如果G<L,那么当G=0时,L已经没有任何意义了,因此最大为dp[G][G]

如果G==L 那么根据二分猜数性质 要猜(1,n)的数字的次数为k=log(n)+1 解得n==2^k-1,所以我们有k次机会可以猜到n,所以dp[G][G]==2^G-1

如果G>L,这里就需要dp了

假设我们猜一个数字为x

如果猜低了,那么我们能猜到的最大数字一定+dp[i-1][j]

如果猜高了,那么我们能猜到的最大数字一定+dp[i-1][j-1]

如果猜对了,那么我们能猜的数字一定+1

因此转移方程为: dp[i][j]=dp[i-1][j]+1+dp[i-1][j-1]

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int dp[30][30];
int main()
{
    int k=1,t;
    int G,L,i,j;
    while(scanf("%d%d",&G,&L))
    {
        if(G==0&&L==0) break;
        memset(dp,0,sizeof(dp));
        for(i=0; i<=G; i++)
        {
            dp[i][0]=i;
            dp[i][i]=pow(2.0,i)-1;//二分猜数
        }
        //dp[i][j]表示有i次机会,j次猜高机会
        for(i=1; i<=G; i++)
        {
            for(j=1; j<=i-1; j++)
            {
                dp[i][j]=dp[i-1][j]+1+dp[i-1][j-1];
            }
            //假设我在i次机会,j次猜高的时候猜了数字x
            //dp[i-1][j-1]代表猜高了,因此范围一定在(1,x-1)即dp[i-1][j-1]
            //+1代表数字x
            //dp[i-1][j]代表数字猜低了,范围是在(x+1,dp[i-1][j]+1)
            //所以 dp[i][j]=dp[i-1][j]+1+dp[i-1][j-1]
        }
        printf("Case %d: ",k++);
        if(L>=G) printf("%d\n",dp[G][G]);//如果机会比猜高机会还少,那么多余的猜高机会没有任何作用
        else printf("%d\n",dp[G][L]);
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值