回しにします。https://www.cnblogs.com/kevinACMer/p/3724671.html
質問の意味:
数直線N + 1点がN、0から開始し、ゲームをプレイする人(0〜Nの番号付け)、またはN、ゲームの終わりよりも大きい場合ポイントに達するあります。すべてのアクションダイスは、ダイスは、彼らはこれらの点に達するとあなたに直接飛ぶことができ、あなたが前方にいくつかの手順を歩いてどのくらいの飛行チェスでの飛行ポイントに似ている。この数直線といくつかの特別なポイントを、投げるために1-6番与えられた点。サイコロの総投資額予測数を探しています。
分析:
DPによって[i]はiがゲームの終わりからも所望の回数を投げ、場所で述べています。明らかDP [n]は0であり、要求がdp [0]です。点の上に直接飛ぶため。VIS例えば配列[]表現され、VIS [A] =それは点Bに直接飛ぶことができる点に到達したときbは、その後明らかDP示し[VIS [A] = DP [A]。プッシュ後方、DP I確率1/6でそれぞれが6可能な状態(即ち、6つの可能なキューブに対応する)以下。したがって、のための(INT X = 1であり、x <= 6; X ++)DP [I] + = DP [I + X] /6.0;dp [I] + = 1; なお、所望のプレイ各可能性の最後の添加後これらの6つの可能性は、単に次の状態、その前の状態の現在の状態を期待するまで追加するので+1は、それが1に(直接投資とサイコロの数として理解される)ことが望ましいです。
コード:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
double dp[100020];
int vis[100020];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m) && (n+m)!=0)
{
memset(vis,-1,sizeof(vis));
memset(dp,0,sizeof(dp));
int a,b;
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
vis[a]=b;
}
for(int i=n-1;i>=0;i--)
{
if(vis[i]==-1)
{
for(int j=1;j<=6;j++)
{
cout<<dp[i+j]/6.0<<endl;
dp[i]+=dp[i+j]/6.0;
cout<<'i'<<" "<<dp[i]<<endl;
}
dp[i]+=1;
cout<<i<<" "<<dp[i]<<endl;
}
else dp[i]=dp[vis[i]];
}
printf("%.4lf\n",dp[0]);
}
return 0;
}