获胜的概率只和下一轮开始前的得分有关,因此根据得分计算概率。
令dp[x]表示从x开始游戏并获胜的概率,目的是求dp[0]的值。
情况1:
当K<=x<=Min(N,K-1+W)时
dp[x]=1。当x>=Min(N,K-1+W)时dp[x]=0;
情况2:
当x<K
dp[x]=
直观的动态规划解法:
class Solution {
public:
double new21Game(int N, int K, int W) {
double dp[K+W];
memset(dp,0,sizeof(dp));
int Min=min(N,K-1+W);
for(int i=K;i<=Min;i++)
{
dp[i]=1;
}
for(int i=K-1;i>=0;i--)
{
double temp=0;
for(int j=i+1;j<=i+W;j++)
temp+=dp[j];
dp[i]=temp/=W;
cout<<i<<" "<<dp[i]<<endl;
}
return dp[0];
}
};
由于时间复杂度为O(N+K*M)所以会超时,不可行。
优化的解法:
当0<=x<K-1时,dp[x]-dp[x+1]=
所以
当x==K-1时(注意N>=K,所以特殊情况可以不考虑)
class Solution {
public:
double new21Game(int N, int K, int W) {
double dp[K+W];
memset(dp,0,sizeof(dp));
double Min=min(N,K-1+W);
for(int i=K;i<=Min;i++)
{
dp[i]=1;
}
for(int i=K-1;i>=0;i--)
{
if(i==K-1)
dp[K-1]=(Min-K+1)/W;
else
{
dp[i]=dp[i+1]+(dp[i+1]-dp[i+W+1])/W;
}
}
return dp[0];
}
};
时间复杂度度为O(min(K+W-1,N))