AOJ1277 Minimal Backgammon
考察
典型的なDP
dp[i][j] :=iターン目にjにいる確率
LだったりBだったり折り返しだったりの判定に順序だけちょっと気を遣う。
#include<iostream> #include<cstdio> #include<vector> #include<string> #include<cstring> #include<functional> #include<stack> #include<queue> #include <iomanip> #include<map> #include<limits> #include<cmath> #include<algorithm> #include<bitset> #include<utility> #include<complex> #include<cstdlib> #include<set> #include<cctype> #define DBG cerr << '!' << endl; #define REP(i,n) for(int (i) = (0);(i) < (n);++i) #define rep(i,s,g) for(int (i) = (s);(i) < (g);++i) #define rrep(i,s,g) for(int (i) = (s);i >= (g);--(i)) #define PB push_back #define MP make_pair #define FI first #define SE second #define SHOW1d(v,n) {for(int W = 0;W < (n);W++)cerr << v[W] << ' ';cerr << endl << endl;} #define SHOW2d(v,i,j) {for(int aaa = 0;aaa < i;aaa++){for(int bbb = 0;bbb < j;bbb++)cerr << v[aaa][bbb] << ' ';cerr << endl;}cerr << endl;} #define ALL(v) v.begin(),v.end() #define Decimal fixed<<setprecision(10) using namespace std; typedef long long ll; typedef vector<int> iv; typedef vector<iv> iiv; typedef vector<string> sv; double mp[111][111]; bool L[111]; bool B[111]; int n,t,l,b; int main() { while(cin >> n >> t >> l >> b,n|t|l|b) { REP(i,111)REP(j,111)mp[i][j] = 0; REP(i,111)L[i] = B[i] = false; mp[0][0] = 1; REP(i,l) { int tmp;cin >> tmp;L[tmp] = true; } REP(i,b) { int tmp;cin >> tmp;B[tmp] = true; } REP(i,t) { REP(j,n) { if(mp[i][j] > 0) { REP(k,6) { int tmp = j + k + 1; int turn = i+1; if(tmp > n)tmp = 2*n - tmp; if(L[tmp])turn++; if(B[tmp])tmp = 0; mp[turn][tmp] += mp[i][j] / 6; } } } } //SHOW2d(mp,t+1,n+1); double ans = 0; REP(i,t+1) { ans += mp[i][n]; } cout << Decimal << ans << endl; } return 0; }