題目大意:
有一個人在猜數字,總共有G次猜測機會,L次猜高的機會。問他能夠猜對的最大數字是什麼。
如果猜錯,那麼G-1,如果是猜高了,那麼需要額外L-1,當猜對或者G<0或者L<0的時候,猜測結束。
一開始把題目理解成:猜低,G-1,猜高L-1,G變爲初始值。但是樣例都不過掉。
解題思路:
根據正確的題意,那麼我們可以很容易想到一個狀態轉移方程:dp[i][j] = dp[i-1][j-1]+dp[i-1][j] 其中i表示剩餘的猜測次數,j表示剩餘的生命線。
這邊,我用了記憶化搜索的方式來計算具體的dp值。當L>G時,多餘的L其實是浪費的,當L=0時,最優的策略就是一個一個的往上猜,所以dp[i][0] = i;
代碼如下:
#include<cstdio>
#include<cstring>
using namespace std;
bool vis[55][55];
int dp[55][55];
int DP(int x,int y)
{
if(y>x)y = x;
if(vis[x][y])return dp[x][y];
vis[x][y]=true;
if(y==0)return dp[x][y]=x;
return dp[x][y]=DP(x-1,y-1)+DP(x-1,y)+1;
}
int main()
{
int n,m,i,j,ca=1;
while(scanf("%d%d",&n,&m)==2)
{
if(n==0&&m==0)break;
memset(vis,0,sizeof(vis));
printf("Case %d: %d\n",ca++,DP(n,m));
}
return 0;
}