大体题意:
一副扑克牌游戏,你要掀n个扑克牌,每个扑克牌上面有数值大小,这个数值大小x代表你要往后走x步,走到最后一个步就不走了!
另一个人也要玩这个游戏,他的起点是1到10随意挑选一个! 除了第一个翻得牌知道以外,其余都不知道,求第二个人最后的终点和第一个人的终点一样的概率!
思路:
只有13个牌,2~11, A是11,J Q K 10是10 ,因此翻牌是10的概率是 4/13, 其余的都是1/14.
我们可以根据第一个人翻牌情况 把他们的位置记录下来!然后倒着枚举位置(倒着枚举要好一些 ,因为目标是后面的位置)
然后第二层循环枚举走的步数,令dp[i]表示翻牌第i个位置的牌 能走到终点的概率!
那么显然 ,假设 k 是第一个人的路径,那么dp[k]都是1.0,然后转移方程就是dp[i] += dp[i + j] * p [j];
最后答案就是 dp[1] + dp[2] + ... + dp[10] 这10个起始位置!
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char cmd[10];
double dp[1500];
int main(){
int n,m;
while(scanf("%d %d",&n,&m) == 2){
int cur = m;
memset(dp,0,sizeof dp);
dp[cur] = 1.0;
for (int i = 0; i < n; ++i){
scanf("%s",cmd);
if (i == n-1)continue;
char ch1 = cmd[0],ch2 = cmd[1];
if (ch1 == 'J' || ch1 == 'Q' || ch1 == 'K' || (ch1 == '1' && ch2 == '0'))cur += 10;
else if (ch1 == 'A') cur += 11;
else cur += ch1 - 48;
dp[cur] = 1.0;
}
for (int i = cur; i >= 1; --i){
if (dp[i] == 1.0)continue;
for (int j = 2; j <= 11; ++j){
if (j == 10) dp[i] += dp[i+j] * 4.0/13.0;
else dp[i] += dp[i+j] * 1.0 / 13.0;
}
}
double ans = 0;
for (int i = 1; i <= 10; ++i)ans += dp[i];
printf("%.15lf\n",ans/10);
}
return 0;
}