HDU-5981 Guess the number(DP)

来源:互联网 发布:python中的readline 编辑:程序博客网 时间:2024/06/17 20:29

Guess the number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 160000/160000 K (Java/Others)
Total Submission(s): 245    Accepted Submission(s): 99


Problem Description
AOA just met a problem when he attended an interview, as shown below:
A and B two people play guessing games. A thinks of a number x between a and b randomly in his mind, and he lets B to guess this number. A will say too small if B’s guess is less than x and A will say yes if B’s guess is just x.Once B’sguess is bigger than x,A won't speak any more.After that,A just nods his head if B’s guess is just x,otherwise shakes his head.The problem is that how many kinds of best guess strategies to make the least number of guesses in the worst situation?
 

Input
Input contains multiple sets of test data and each of them occupies one line,including two integersa, b(1≤a≤b≤5 * 10^6),on behalf of range of the number.Input to the end of the file.
 

Output
For each set of input, output one line containing two integers. The first one represents the least number of times of guessing in the worst situation. The second one represents the number of best guess method modulo 100000073.
 

Sample Input
1 5
 

Sample Output
3 3
Hint
B can guess the number in A's mind up to 3 times in the worst case.The first method,B can guess in the order of (2,4,5)The second method,B can guess in the order of (3,4,5)The third method,B can guess in the order of (3,5)Each method is up to three times.

题意:A和B玩一个游戏:A在[L,R]之间随机选取一个数X,之后由B来猜这个数,如果猜的数比X小,

则A就告诉B你猜的数小了,如果猜的数等于X则游戏结束,如果猜的数大于X,则在这之后A只会回答B
是否猜对了,而不会告诉B是否猜小了。问:在最坏的情况下,B猜到X时最少需要猜多少次,并输出方案数

题解:这道题其实有一道一模一样的题目:有n层楼,2颗鸡蛋,鸡蛋有个强度:可以在第X层楼摔下去且不
会碎,要求用这2颗鸡蛋测试X是哪一层楼。

假设需要k次测试就能测完,那么我们该如何进行测试呢?因为第一颗蛋碎了,第二颗就只能一层一层地往上
试。因此第一次测试时,就应该选择第k层进行测试,如果在第k层碎了,则从第1层开始遍历到第k-1层,一共
需要k次;如果在第k层没有碎,那么还剩k-1次,我们就选择在k+k-1层进行测试,然后一直进行下去。

计算下来,进行k次测试,最高可以测试的层数为:k+(k-1)+...+1=k(k+1)/2

可以用数组f[x]记录有x层时需要测试的次数,状态转移的方法见代码注释

#include<bits/stdc++.h>using namespace std;typedef long long LL;const int MX = 5e6 + 5;const int mod = 100000073;/******f[x]:有x层楼时需要测试的次数p[x]:从第P[x]楼开始需要至少测试x次cnt[x]:有x层楼时的方案数sum[x]:cnt的前缀和******/int f[MX],p[MX],cnt[MX],sum[MX];int main(){    for(int x=0,index=1;index<MX;){        if(x*(x+1)/2<index) p[++x]=index;        f[index++]=x;    }    cnt[1]=sum[0]=1;sum[1]=2;    /******    设现在有x层楼,需要进行f[x]次测试,那么它的方案一定是从f[x]-1转移过来的,    我们设变量y,有f[y]=f[x]-1,很明显p[f[x]-1]<=y<p[f[x]]    通过上面的分析可知:如果测试次数有k次,那么第一次测试可以选择第k层,    因此第x层可以由第[x-k,x-1]层转移过来,但由于策略要选取最优的,因此上界为p[f[i]]-1    ******/    for(int i=2;i<MX;i++){        int st=i-f[i],ed=p[f[i]]-1;        cnt[i]=(sum[ed]-sum[st-1]+mod)%mod;        sum[i]=(sum[i-1]+cnt[i])%mod;    }    int L,R;    while(~scanf("%d%d",&L,&R)) printf("%d %d\n",f[R-L+1],cnt[R-L+1]);    return 0;}