zoj1503-One Person "The Price is Right"

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=503

// 题目大意:每个人允许猜 G 次,有 L 生命线。猜低或猜高了,耗费一次猜得机会,猜高了,还

     //        会浪费一生命线。

     // dp

     // 先从搜索考虑。设f(g,l)表示有g次机会,l条生命线时可以猜到的最大价格范围。

     // 那么,f(g,l)应该由三段范围组成:猜低了,用剩下的机会还能猜出f(g-1,l)范围的价格;

     // 猜得正好,可以猜出1个价格;猜高了,用剩下的机会还能猜出f(g-1,l-1)范围的价格。

     // 拼起来,就有f(g,l)=f(g-1,l)+1+f(g-1,l-1)。

     // 然后考虑一下边界情况:当g=0时,游戏结束了,所以f(0,l)=0;

     // 当l=0时,价格不能再猜高了,只能往下再摸索g次,所以f(g,0)=g。

     // 这样就可以用搜索来解决这个题了。再转成记忆化搜索就行了。

     // 也可以观察出阶段,自底向上推。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<bitset>

using namespace std;

int main()
{
	int dp[ 32 ][ 32 ];
	int i , j ;
	memset( dp , 0 , sizeof( dp ) ) ;
	for( i = 0 ; i < 32 ; ++i )
		dp[ i ][ 0 ] = i ;
	for( i = 1 ; i < 32 ; ++i )
	{
		for( j = 1 ; j <= i ; ++j )
			dp[ i ][ j ] = dp[ i - 1 ][ j ] + dp[ i - 1 ][ j - 1 ] + 1 ;
		for( ; j < 32 ; ++j )
			dp[ i ][ j ] = dp[ i ][ i ] ;
	}
	int g , l ;
	int temp = 1 ;
	while( cin >> g >> l )
	{
		if( !( g + l ) )
			return 0 ;
		printf("Case %d: %d\n", temp ++ , dp[ g ][ l ] ) ;
	} 
}


你可能感兴趣的:(dp)