Problem:
Problem C: General of Taiko
Problem
とあるゲームセンターには、曲に合わせて流れてくる譜面通りに和太鼓を叩くゲームがあります。
譜面は長さ
L
のセルからなり、各セルには何もない、またはノートと呼ばれるプレイヤーがとるべき行動を表した記号があります。
ノートは2種類ありそれぞれ、和太鼓の面を叩く「トン」、和太鼓の縁を叩く「コツ」があります。
これらのノートに合わせて和太鼓を叩くと得点を得ることができます。
この得点の合計が10000点以上であればクリアとなります。
このとき、プレイヤーが曲をクリアできる確率を求めなさい。ただし、プレイヤーは常に最適な行動をとることにします。
プレイヤーが譜面通りに和太鼓を叩く精度は11段階あり、それぞれ、
0%, 10%, 20%, ..., 90%, 100%の確率で譜面通りに和太鼓を叩くことができます。
上記の二種類の動作は右腕と左腕どちらででも行うことができます。
プレイヤーの情報として、それぞれの腕で行った場合の精度の安定率を表す値が16種類、下記のように与えられます。
lt
_
lt
lt
_
rt
lt
_
lk
lt
_
rk
rt
_
lt
rt
_
rt
rt
_
lk
rt
_
rk
lk
_
lt
lk
_
rt
lk
_
lk
lk
_
rk
rk
_
lt
rk
_
rt
rk
_
lk
rk
_
rk
ただし、
lt
は左腕でトン,
rt
は右腕でトン,
lk
は左腕でコツ,
rk
は右腕でコツの動作を表します。
例えば、
lt
_
rk
は左腕でトンのあとに右腕でコツを行った時の精度の安定の度合いを表し、この値によって左腕でトンのあとに右腕でコツを行うときの精度が、下記のように変化します。
プレイヤーの精度 = max(0, (精度の安定率 - 10) * 10 + 一つ前の精度) (%)
曲の情報は以下のとおりです。
曲の長さを表す
L
、譜面を表す
L
個の数字
s
i
(0 ≤
i
<
L
)で示される。譜面の先頭は
s
0
である。
s
i
の値は以下の3つです。
0 ... ノートなし
1 ... トン
2 ... コツ
プレイヤーが最初に和太鼓を叩くときの精度は100%です。
また、プレイヤーは譜面を無視することができます。
ノートがなかったり、ノートを無視した場合、プレイヤーの精度は100%になります。
各ノートに合わせて和太鼓を叩いたときの得点は下記のようになります。
得点 =
A
+
B
* min(コンボ数, 10)
この問題におけるコンボ数とは、連続してノートに合わせて和太鼓を叩けた数です。
プレイヤーがノートに合わせて叩いた場合、上記の式を元に得点が入り、その後にコンボ数が1増えます。
ノートに合わせて和太鼓を叩けなかった場合、コンボが途切れ、コンボ数が0になります。
Input
入力は複数のデータセットからなります。
各データセットは以下のとおりです。
lt
_
lt
lt
_
rt
lt
_
lk
lt
_
rk
rt
_
lt
rt
_
rt
rt
_
lk
rt
_
rk
lk
_
lt
lk
_
rt
lk
_
lk
lk
_
rk
rk
_
lt
rk
_
rt
rk
_
lk
rk
_
rk
L
s
0
s
1
s
2
…
s
L - 1
A
B
入力の終わりは負の整数4つからなります。
Constraints
入力は以下の条件を満たします。
0 <
L
≤ 100
0 ≤ 精度の安定率 ≤ 10
精度の安定率は整数
0 <
A
,
B
≤ 10000
A
と
B
はともに100の倍数
データセットの数は100個以下
Output
各入力に対して、クリアできる確率を1行で出力しなさい。
ただし、出力は0.001以下の誤差を含んでも良いです。
Sample Input
9 0 0 0
0 9 0 0
0 0 0 0
0 0 0 0
5
1 1 1 1 1
1000 500
10 10 10 10
10 10 10 10
10 10 10 10
10 10 10 10
5
1 0 2 0 1
1000 2000
3 8 6 10
0 1 6 8
10 2 4 7
8 6 6 8
19
2 2 0 2 2 0 2 1 0 1 2 0 1 2 0 1 0 2 2
200 100
-1 -1 -1 -1
Sample Output
0.3024000000
0.0000000000
0.5120000000

Submitted solutions:

code_snippet: #include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cassert>
#include <random>
#include <iomanip>
#pragma GCC optimize("O3")
using namespace std;

#define ll long long
// #define pii pair<ll, int>
// #define pq priority_queue <pii, vector<pii>, greater<pii>>

// std::mt19937 rand(129365);

//lt_lt 0 lt_Rt 1 lt_lK 2 lt_rk 3
//Rt_lt 4 rt_rt 5 rt_lk 6 rt_rk 7
//lK_lt 8 lk_rt 9 lk_lk 10 lk_rk 11
//rk_lt 12 rk_rt 13 rk_lk 14 rk_rk 15

int vals[16];
int n, a, b;
int s[100];

double prob_l(int i, int acc, int combo, int score);
double prob_r(int i, int acc, int combo, int score);
double prob_skip(int i, int acc, int combo, int score);

double dpl[101][11][11][101];
double dpr[101][11][11][101];
double dps[101][11][11][101];

double prob_l(int i, int acc, int combo, int score){
    if(score <= 0) return 1.0;
    else if(i == n) return 0.0;
    if(combo > 10) combo = 10;
    if(dpl[i][acc][combo][score] >= 0) return dpl[i][acc][combo][score] ;
    assert(s[i-1] != 0);
    if(s[i] == 0){
        dpl[i][acc][combo][score] = prob_skip(i+1, 10, combo, score);
        // cout << "l " <<  i << ' ' << acc << ' ' << combo << ' ' << score << ' ' << dpl[i][acc][combo][score] << endl;
        return dpl[i][acc][combo][score];
    }
    int d = a + b * combo;
    int mask;
    if(s[i-1] == 1) mask = 0; //ton left
    else mask = 8; //kotsu left
    if(s[i] == 1) mask |= 0;//ton
    else mask |= 2;//kotsu
    //try l
    int lacc = max(0, vals[mask] - 10 + acc);
    double p_next_l_hit = prob_l(i+1, lacc, combo + 1, score - d);
    double p_next_l_miss = prob_l(i+1, lacc, 0, score);
    double p_next_l = p_next_l_hit * lacc / 10 + p_next_l_miss * (10 - lacc) / 10;
    //try r
    int racc = max(0, vals[mask | 1] - 10 + acc);
    double p_next_r_hit = prob_r(i+1, racc, combo + 1, score - d);
    double p_next_r_miss = prob_r(i+1, racc, 0, score);
    double p_next_r = p_next_r_hit * racc / 10 + p_next_r_miss * (10 - racc) / 10;
    //try skip
    double p_next_skip = prob_skip(i+1, 10, 0, score);

    dpl[i][acc][combo][score] = max(max(p_next_l, p_next_r), p_next_skip);
        // cout << "l " <<  i << ' ' << acc << ' ' << combo << ' ' << score << ' ' << dpl[i][acc][combo][score] << endl;
    return dpl[i][acc][combo][score];
}
double prob_r(int i, int acc, int combo, int score){
    if(score <= 0) return 1.0;
    else if(i == n) return 0.0;
    if(combo > 10) combo = 10;
    if(dpr[i][acc][combo][score] >= 0) return dpr[i][acc][combo][score] ;
    assert(s[i-1] != 0);
    if(s[i] == 0){
        dpr[i][acc][combo][score] = prob_skip(i+1, 10, combo, score);
        // cout << "r " <<  i << ' ' << acc << ' ' << combo << ' ' << score << ' ' << dpr[i][acc][combo][score] << endl;
        return dpr[i][acc][combo][score];
    }
    int d = a + b * combo;

    int mask;
    if(s[i-1] == 1) mask = 4; //ton right
    else mask = 12; //kotsu right
    if(s[i] == 1) mask |= 0;//ton
    else mask |= 2;//kotsu
    //try l
    int lacc = max(0, vals[mask] - 10 + acc);
    double p_next_l_hit = prob_l(i+1, lacc, combo + 1, score - d);
    double p_next_l_miss = prob_l(i+1, lacc, 0, score);
    double p_next_l = p_next_l_hit * lacc / 10 + p_next_l_miss * (10 - lacc) / 10;
    //try r
    int racc = max(0, vals[mask | 1] - 10 + acc);
    double p_next_r_hit = prob_r(i+1, racc, combo + 1, score - d);
    double p_next_r_miss = prob_r(i+1, racc, 0, score);
    double p_next_r = p_next_r_hit * racc / 10 + p_next_r_miss * (10 - racc) / 10;
    //try skip
    double p_next_skip = prob_skip(i+1, 10, 0, score);

    dpr[i][acc][combo][score] = max(max(p_next_l, p_next_r), p_next_skip);
        // cout << "r " <<  i << ' ' << acc << ' ' << combo << ' ' << score << ' ' << dpr[i][acc][combo][score] << endl;
    return dpr[i][acc][combo][score];
}
double prob_skip(int i, int acc, int combo, int score){
    if(score <= 0) return 1.0;
    else if(i == n) return 0.0;
    if(combo > 10) combo = 10;
    if(dps[i][acc][combo][score] >= 0) return dps[i][acc][combo][score] ;
    int d = a + b * combo;
    if(s[i] == 0){
        dps[i][acc][combo][score] = prob_skip(i+1, 10, combo, score);
        // cout << "s " << i << ' ' << acc << ' ' << combo << ' ' << score << ' ' << dps[i][acc][combo][score] << endl;
        return dps[i][acc][combo][score];
    }
    else{
        double p_next_l = prob_l(i+1, 10, combo + 1, score - d);
        double p_next_r = prob_r(i+1, 10, combo + 1, score - d);
        double p_next_skip = prob_skip(i+1, 10, 0, score);

        dps[i][acc][combo][score] = max(max(p_next_l, p_next_r), p_next_skip);
        // cout << "s " <<  i << ' ' << acc << ' ' << combo << ' ' << score << ' ' << dps[i][acc][combo][score] << endl;
        return dps[i][acc][combo][score];
    }
}

int main(){
    while(true){
        for(int i = 0; i < 16; i++){
            cin >> vals[i];
            if(i == 3 and vals[0] < 0){
                return 0;
            }
        }
        cin >> n;
        for(int i = 0; i < n; i++){
            cin >> s[i];
        }
        for(int i = 0; i <= n; i++){
            for(int j = 0; j <= 10; j++){
                for(int k = 0; k <= 10; k++){
                    for(int s = 0; s <= 100; s++){
                        dpl[i][j][k][s] = 
                            dpr[i][j][k][s] = 
                            dps[i][j][k][s] = -1;
                    }
                }
            }
        }
        cin >> a >> b;
        a /= 100, b /= 100;
        if(s[0] == 0){
            cout << setprecision(10) << prob_skip(1, 10, 0, 100) << endl;
        }
        else{
            double sl = prob_l(1, 10, 1, 100 - a);
            double sr = prob_r(1, 10, 1, 100 - a);
            double ss = prob_skip(1, 10, 0, 100);
            cout << setprecision(10) << max(max(sl, sr), ss) << endl;
        }
    }
}
accuracy: 1
time_ms: 920
memory_kb: 32532
final_rank: 1

code_snippet: #include <iostream>
using namespace std;

// 問題文に曖昧なところがあって良くわからない．
int Accuracy[5][5];
int L, S[109];
int A;
int B;
double dp[109][109][12][12][5]; // (pos, 得点, コンボ, 精度, 前の腕)

double solve() {
	// DP Init
	for (int i = 0; i <= L + 1; i++) {
		for (int j = 0; j <= 100; j++) {
			for (int k = 0; k <= 10; k++) {
				for (int l = 0; l <= 10; l++) {
					for (int m = 0; m <= 4; m++) dp[i][j][k][l][m] = 0.0;
				}
			}
		}
	}
	for (int i = 0; i <= 10; i++) {
		for (int j = 0; j <= 10; j++) dp[L + 1][100][i][j][4] = 1.0;
	}

	// Dynamic Programming
	for (int i = L; i >= 0; i--) {
		for (int j = 0; j <= 100; j++) {
			for (int k = 0; k <= 10; k++) {
				for (int l = 0; l <= 10; l++) {
					for (int m = 0; m <= 4; m++) {
						for (int nex = 0; nex <= 4; nex++) {
							if (S[i] != 1 && (nex == 0 || nex == 1)) continue;
							if (S[i] != 2 && (nex == 2 || nex == 3)) continue;
							double score = 0;

							// 成功する場合
							if (true) {
								int nex_pos = i + 1;
								int nex_score = j;
								int nex_combo = k;
								int nex_seido = max(0, l + Accuracy[m][nex] - 10);
								int nex_state = nex;
								if (S[i] == 1 && (nex == 0 || nex == 1)) { nex_score = min(100, nex_score + A + B * k); nex_combo = min(10, nex_combo + 1); }
								if (S[i] == 2 && (nex == 2 || nex == 3)) { nex_score = min(100, nex_score + A + B * k); nex_combo = min(10, nex_combo + 1); }
								if (nex == 4) { nex_seido = 10; }
								if (S[i] == 1 && nex == 4) { nex_combo = 0; }
								if (S[i] == 2 && nex == 4) { nex_combo = 0; }
								score += 0.1 * nex_seido * dp[nex_pos][nex_score][nex_combo][nex_seido][nex_state];
							}

							// 失敗する場合
							if (nex != 4) {
								int nex_pos = i + 1;
								int nex_score = j;
								int nex_combo = 0;
								int nex_seido = max(0, l + Accuracy[m][nex] - 10);
								int nex_state = nex;
								score += 0.1 * (10 - nex_seido) * dp[nex_pos][nex_score][nex_combo][nex_seido][nex_state];
							}
							dp[i][j][k][l][m] = max(dp[i][j][k][l][m], score);
						}
					}
				}
			}
		}
	}

	// Return
	return dp[0][0][0][10][4];
}

int main() {
	while (true) {
		// Step 1. Input
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) Accuracy[i][j] = 10;
		}
		cin >> Accuracy[0][0] >> Accuracy[0][1] >> Accuracy[0][2] >> Accuracy[0][3]; if (Accuracy[0][0] == -1) break;
		cin >> Accuracy[1][0] >> Accuracy[1][1] >> Accuracy[1][2] >> Accuracy[1][3];
		cin >> Accuracy[2][0] >> Accuracy[2][1] >> Accuracy[2][2] >> Accuracy[2][3];
		cin >> Accuracy[3][0] >> Accuracy[3][1] >> Accuracy[3][2] >> Accuracy[3][3];
		cin >> L;
		for (int i = 0; i < L; i++) cin >> S[i];
		cin >> A >> B;
		A /= 100; B /= 100;

		// Step 2. Dynamic Programming
		double Answer = solve();
		printf("%.12lf\n", Answer);
	}
	return 0;
}
accuracy: 1
time_ms: 6700
memory_kb: 66900
final_rank: 12

code_snippet: #include <iostream>
using namespace std;

// 問題文に曖昧なところがあって良くわからない．
int Accuracy[5][5];
int L, S[109];
int A;
int B;
double dp[109][109][12][12][5]; // (pos, 得点, コンボ, 精度, 前の腕)

double solve() {
	// DP Init
	for (int i = 0; i <= L + 1; i++) {
		for (int j = 0; j <= 100; j++) {
			for (int k = 0; k <= 10; k++) {
				for (int l = 0; l <= 10; l++) {
					for (int m = 0; m <= 4; m++) dp[i][j][k][l][m] = 0.0;
				}
			}
		}
	}
	for (int i = 0; i <= 10; i++) {
		for (int j = 0; j <= 10; j++) dp[L + 1][100][i][j][4] = 1.0;
	}

	// Dynamic Programming
	for (int i = L; i >= 0; i--) {
		for (int j = 0; j <= 100; j++) {
			for (int k = 0; k <= 10; k++) {
				for (int l = 0; l <= 10; l++) {
					for (int m = 0; m <= 4; m++) {
						for (int nex = 0; nex <= 4; nex++) {
							if (S[i] != 1 && (nex == 0 || nex == 1)) continue;
							if (S[i] != 2 && (nex == 2 || nex == 3)) continue;

							// 成功する場合
							if (true) {
								int nex_pos = i + 1;
								int nex_score = j;
								int nex_combo = k;
								int nex_seido = max(0, l + Accuracy[m][nex] - 10);
								int nex_state = nex;
								if (S[i] == 1 && (nex == 0 || nex == 1)) { nex_score = min(100, nex_score + A + B * k); nex_combo = min(10, nex_combo + 1); }
								if (S[i] == 2 && (nex == 2 || nex == 3)) { nex_score = min(100, nex_score + A + B * k); nex_combo = min(10, nex_combo + 1); }
								if (nex == 4) { nex_seido = 10; }
								if (S[i] == 1 && nex == 4) { nex_combo = 0; }
								if (S[i] == 2 && nex == 4) { nex_combo = 0; }
								dp[i][j][k][l][m] = max(dp[i][j][k][l][m], 0.1 * nex_seido * dp[nex_pos][nex_score][nex_combo][nex_seido][nex_state]);
							}

							// 失敗する場合
							if (nex != 4) {
								int nex_pos = i + 1;
								int nex_score = j;
								int nex_combo = 0;
								int nex_seido = max(0, l + Accuracy[m][nex] - 10);
								int nex_state = nex;
								dp[i][j][k][l][m] = max(dp[i][j][k][l][m], 0.1 * (10 - nex_seido) * dp[nex_pos][nex_score][nex_combo][nex_seido][nex_state]);
							}
						}
					}
				}
			}
		}
	}

	// Return
	return dp[0][0][0][10][4];
}

int main() {
	while (true) {
		// Step 1. Input
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) Accuracy[i][j] = 10;
		}
		cin >> Accuracy[0][0] >> Accuracy[0][1] >> Accuracy[0][2] >> Accuracy[0][3]; if (Accuracy[0][0] == -1) break;
		cin >> Accuracy[1][0] >> Accuracy[1][1] >> Accuracy[1][2] >> Accuracy[1][3];
		cin >> Accuracy[2][0] >> Accuracy[2][1] >> Accuracy[2][2] >> Accuracy[2][3];
		cin >> Accuracy[3][0] >> Accuracy[3][1] >> Accuracy[3][2] >> Accuracy[3][3];
		cin >> L;
		for (int i = 0; i < L; i++) cin >> S[i];
		cin >> A >> B;
		A /= 100; B /= 100;

		// Step 2. Dynamic Programming
		double Answer = solve();
		printf("%.12lf\n", Answer);
	}
	return 0;
}
accuracy: 0.2857142857142857
time_ms: 720
memory_kb: 66736
final_rank: 18

code_snippet: #include "bits/stdc++.h"
using namespace std;
using ld =  double;
const ld eps = 1e-9;
const int COMB_MAX = 11;
int per[5][5];
ld dp[101][COMB_MAX + 1][101][5][11];

int A, B;
ld solve(vector<int>&nodes, int now, int combo,int score, int preuse,int preacc) {
	if (dp[now][combo][score][preuse][preacc] > -eps) {
		return dp[now][combo][score][preuse][preacc];
	}else if (now == nodes.size()) {
		if (score == 100) {
			int a;
			a = 1;
			a++;
		}
		dp[now][combo][score][preuse][preacc] = score >= 100;
	}
	else {

		ld ans = 0;
		if (nodes[now] == 0) {
			dp[now][combo][score][preuse][preacc] = solve(nodes, now + 1, combo, score, 4, 10);
		}
		else if (score >= 100) {
			dp[now][combo][score][preuse][preacc] = 1.0l;
		}
		else {
			for (int nextuse = 0; nextuse < 5; ++nextuse) {
				int nextscore(score);
				int nextcombo(combo);
				int kot = nextuse == 4 ? 0 : nextuse % 2+1;
				if (kot&&nodes[now] == kot) {
					nextcombo++;
					nextscore += A + B*min(combo, 10);
				}
				else {
					nextcombo = 0;
				}
				if (nextcombo > COMB_MAX) {
					nextcombo = min(nextcombo, COMB_MAX);
				}
				nextscore = min(nextscore, 100);
				int nextacc = nextuse == 4 ? 10 : max(0, ((per[preuse][nextuse] - 10) * 10 + preacc*10) / 10);
				assert(nextacc <= 10);
				ld nans = 0;
				{
					if (nextacc) {
						nans += (ld(nextacc) / 10)*solve(nodes, now + 1, nextcombo, nextscore, nextuse, nextacc);
					}
					nans += (1.0l-ld(nextacc) / 10)*solve(nodes, now + 1, 0, score, nextuse, nextacc);
				}
				ans = max(ans, nans);
			}
			dp[now][combo][score][preuse][preacc] = ans;
		}
		
	}
	return dp[now][combo][score][preuse][preacc];

}

int main() {
	cout << setprecision(10) << fixed;
	while (1) {
		for (int i = 0; i < 101; i++) {
			for (int j = 0; j <=COMB_MAX ; ++j) {
				for (int k = 0; k < 101; ++k) {
					for (int l = 0; l < 5; ++l) {
						for (int m = 0; m < 11; ++m) {
							dp[i][j][k][l][m] = -1;
						}
					}
				}
			}
		}
		for (int i = 0; i < 2; ++i) {
			for (int j = 0; j < 2; ++j) {
				int from = j * 2 + i;
				for (int k = 0; k < 2; ++k) {
					for (int l = 0; l < 2; ++l) {
						int to = l * 2 + k;
						cin >> per[from][to];
						if (per[from][to] < -0.5)return 0;
					}
				}
			}
		}
		for (int i = 0; i < 5; ++i) {
			per[i][4] = 10;
			per[4][i] = 10;
		}
		int L; cin >> L;
		vector<int>nodes(L);
		for (int i = 0; i < L; ++i) {
			cin >> nodes[i];
		} cin >> A >> B;
		A /= 100;
		B /= 100;
		ld ans = solve(nodes, 0, 0, 0, 4, 10);
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 4070
memory_kb: 55904
final_rank: 7

code_snippet: #include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)
using namespace std;
typedef long long LL;
const int MAXA = 100;
const int MAXP = 10000;
int L;
//bool used[105][5][11][101][11];
double memo[101][5][11][101][11];
inline double get(int idx, int last, int ac, int point, int cmb) {
    if(point >= 100) point = 100;
    if(cmb >= 11) cmb = 10;
    if(idx == L) return (point == 100 ? 1.0 : 0.0);
    // assert(point % 100 == 0);
    //point /= 100;
    // assert(ac % 10 == 0);
    //ac /= 10;
    // assert(idx >= 0 && idx < 101);
    // assert(last >= 0 && last < 5);
    // assert(ac >= 0 && ac < 11);
    // assert(point >= 0 && point < 101);
    // assert(cmb >= 0 && cmb < 11);
    //assert(used[idx][last][ac][point][cmb]);
    return memo[idx][last][ac][point][cmb];
}

inline void Set(int idx, int last, int ac, int point, int cmb, double val) {
    //used[idx][last][ac][point][cmb] = true;
    //assert(point % 100 == 0);
    //point /= 100;
    //assert(ac % 10 == 0);
    //ac /= 10;
    // assert(idx >= 0 && idx < 101);
    // assert(last >= 0 && last < 5);
    // assert(ac >= 0 && ac < 11);
    // assert(point >= 0 && point < 101);
    // assert(cmb >= 0 && cmb < 11);
    memo[idx][last][ac][point][cmb] = val;
}

int main(){
    while(true) {
        //memset(used, 0, sizeof(used));

        int D[5][5];
        REP(y, 4) REP(x, 4) cin >> D[y][x];
        if(D[0][0] < 0) break;

        cin >> L;

        vector<int> s(L);
        REP(i, L) cin >> s[i];

        int A, B;
        cin >> A >> B;
        A /= 100;
        B /= 100;
        double probA[11] = {};
        double probB[11] = {};
        REP(i, 11) probA[i] = i / 10.0;
        REP(i, 11) probB[i] = (10.0-i) / 10.0;

        for(int i = L - 1; i >= 0; i--) {
            for(int last = 0; last < 5; last++) {
                for(int ac = 0; ac <= 10; ac ++) {
                    for(int point = 0; point <= 100; point ++) {
                        for(int cmb = 0; cmb <= 10; cmb++) {
                            double res = 0.0;
                            if(s[i] == 1) for(int act = 0; act < 2; act++) {
                                int nac = 10;
                                if(last != 4) {
                                    nac = max(0, (D[last][act] - 10) + ac);
                                }

                                int ncmb = cmb + 1;
                                int npoint = point + A + B * cmb;
                                // if(i == 0 && last == 4 && ac == 100 && point == 0 && cmb == 0) {
                                //     printf("i = %d last = %d ac = %d point = %d cmb = %d act = %d res = %f\n",
                                //             i+1, act, nac, npoint, ncmb, act, (double)ac / 100.0 * get(i+1, act, nac, npoint, ncmb)
                                //             );
                                // }
                                double cand = 
                                        probA[nac] * get(i+1, act, nac, npoint, ncmb) +
                                        probB[nac] * get(i+1, act, nac,  point,    0);
                                if(res < cand) {
                                    res = cand;
                                }

                            }
                            if(s[i] == 2) for(int act = 2; act < 4; act++) {
                                int nac = 10;
                                if(last != 4) {
                                    nac = max(0, (D[last][act] - 10) + ac);
                                }

                                int ncmb = cmb + 1;
                                int npoint = point + A + B * cmb;
                                // if(i == 0 && last == 4 && ac == 100 && point == 0 && cmb == 0) {
                                //     printf("i = %d last = %d ac = %d point = %d cmb = %d act = %d res = %f\n",
                                //             i+1, act, nac, npoint, ncmb, act, (double)ac / 100.0 * get(i+1, act, nac, npoint, ncmb)
                                //             );
                                // }
                                double cand = 
                                        probA[nac] * get(i+1, act, nac, npoint, ncmb) +
                                        probB[nac] * get(i+1, act, nac,  point,    0);
                                if(res < cand) {
                                    res = cand;
                                }

                            }
                            {
                                int nac = 10;
                                int ncmb = (s[i] == 0 ? cmb : 0);
                                int npoint = point;
                                double cand = get(i+1, 4, nac, npoint, ncmb);
                                if(res < cand) {
                                    res = cand;
                                }
                            }
                            // if(i == 0 && last == 4 && ac == 100 && point == 0 && cmb == 0) {
                            //     printf("i = %d last = %d ac = %d point = %d cmb = %d act = %d res = %f\n",
                            //             i, last, ac, point, cmb, ACT, res);
                            // }
                            Set(i, last, ac, point, cmb, res);
                        }
                    }
                }
            }
        }

        printf("%.12f\n", get(0, 4, 10, 0, 0));
    }
    return 0;
}
accuracy: 1
time_ms: 6040
memory_kb: 48948
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)
using namespace std;
typedef long long LL;
const int MAXA = 100;
const int MAXP = 10000;
int L;
//bool used[105][5][11][101][11];
double memo[101][5][11][101][11];
double get(int idx, int last, int ac, int point, int cmb) {
    if(point >= 100) point = 100;
    if(cmb >= 11) cmb = 10;
    if(idx == L) return (point == 100 ? 1.0 : 0.0);
    // assert(point % 100 == 0);
    //point /= 100;
    // assert(ac % 10 == 0);
    //ac /= 10;
    // assert(idx >= 0 && idx < 101);
    // assert(last >= 0 && last < 5);
    // assert(ac >= 0 && ac < 11);
    // assert(point >= 0 && point < 101);
    // assert(cmb >= 0 && cmb < 11);
    //assert(used[idx][last][ac][point][cmb]);
    return memo[idx][last][ac][point][cmb];
}

void Set(int idx, int last, int ac, int point, int cmb, double val) {
    //used[idx][last][ac][point][cmb] = true;
    //assert(point % 100 == 0);
    //point /= 100;
    //assert(ac % 10 == 0);
    //ac /= 10;
    // assert(idx >= 0 && idx < 101);
    // assert(last >= 0 && last < 5);
    // assert(ac >= 0 && ac < 11);
    // assert(point >= 0 && point < 101);
    // assert(cmb >= 0 && cmb < 11);
    memo[idx][last][ac][point][cmb] = val;
}

int main(){
    while(true) {
        //memset(used, 0, sizeof(used));

        int D[5][5];
        REP(y, 4) REP(x, 4) cin >> D[y][x];
        if(D[0][0] < 0) break;

        cin >> L;

        vector<int> s(L);
        REP(i, L) cin >> s[i];

        int A, B;
        cin >> A >> B;
        A /= 100;
        B /= 100;
        double probA[11] = {};
        double probB[11] = {};
        REP(i, 11) probA[i] = i / 10.0;
        REP(i, 11) probB[i] = (10.0-i) / 10.0;

        for(int i = L - 1; i >= 0; i--) {
            for(int last = 0; last < 5; last++) {
                for(int ac = 0; ac <= 10; ac ++) {
                    for(int point = 0; point <= 100; point ++) {
                        for(int cmb = 0; cmb <= 10; cmb++) {
                            double res = 0.0;
                            if(s[i] == 1) for(int act = 0; act < 2; act++) {
                                int nac = 10;
                                if(last != 4) {
                                    nac = max(0, (D[last][act] - 10) + ac);
                                }

                                int ncmb = cmb + 1;
                                int npoint = point + A + B * cmb;
                                // if(i == 0 && last == 4 && ac == 100 && point == 0 && cmb == 0) {
                                //     printf("i = %d last = %d ac = %d point = %d cmb = %d act = %d res = %f\n",
                                //             i+1, act, nac, npoint, ncmb, act, (double)ac / 100.0 * get(i+1, act, nac, npoint, ncmb)
                                //             );
                                // }
                                double cand = 
                                        probA[nac] * get(i+1, act, nac, npoint, ncmb) +
                                        probB[nac] * get(i+1, act, nac,  point,    0);
                                if(res < cand) {
                                    res = cand;
                                }

                            }
                            if(s[i] == 2) for(int act = 2; act < 4; act++) {
                                int nac = 10;
                                if(last != 4) {
                                    nac = max(0, (D[last][act] - 10) + ac);
                                }

                                int ncmb = cmb + 1;
                                int npoint = point + A + B * cmb;
                                // if(i == 0 && last == 4 && ac == 100 && point == 0 && cmb == 0) {
                                //     printf("i = %d last = %d ac = %d point = %d cmb = %d act = %d res = %f\n",
                                //             i+1, act, nac, npoint, ncmb, act, (double)ac / 100.0 * get(i+1, act, nac, npoint, ncmb)
                                //             );
                                // }
                                double cand = 
                                        probA[nac] * get(i+1, act, nac, npoint, ncmb) +
                                        probB[nac] * get(i+1, act, nac,  point,    0);
                                if(res < cand) {
                                    res = cand;
                                }

                            }
                            {
                                int nac = 10;
                                int ncmb = (s[i] == 0 ? cmb : 0);
                                int npoint = point;
                                double cand = get(i+1, 4, nac, npoint, ncmb);
                                if(res < cand) {
                                    res = cand;
                                }
                            }
                            // if(i == 0 && last == 4 && ac == 100 && point == 0 && cmb == 0) {
                            //     printf("i = %d last = %d ac = %d point = %d cmb = %d act = %d res = %f\n",
                            //             i, last, ac, point, cmb, ACT, res);
                            // }
                            Set(i, last, ac, point, cmb, res);
                        }
                    }
                }
            }
        }

        printf("%.12f\n", get(0, 4, 10, 0, 0));
    }
    return 0;
}
accuracy: 1
time_ms: 6030
memory_kb: 48952
final_rank: 10

code_snippet: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
#include <cctype>
#include <utility>
 
using namespace std;
 
typedef long long ll;
typedef pair <int,int> P;
typedef pair <int,P > PP;
 
int tx[] = {0,1,0,-1};
int ty[] = {-1,0,1,0};
 
static const double EPS = 1e-8;

double dp[101][11][101][11][5];//dp[note_i][prev_combo][prev_score][prev_stability][prev_action]

int main(){
  while(true){
    //lt rt lk rk
    int stability[4][4];
    for(int i = 0; i < 4; i++){
      int count = 0;
      for(int j = 0; j < 4; j++){
        scanf("%d",&stability[i][j]);
        if(i == 0 && stability[i][j] == -1){
          count++;
        }
      }
      if(count >= 4) goto over;
    }
    int len;
    scanf("%d",&len);
    
    int notes[101];
    
    //0:none 1:t 2:k
    for(int note_i = 0; note_i < len; note_i++){
      scanf("%d",&notes[note_i]);
    }
    int A,B;
    scanf("%d %d",&A,&B);
    
    memset(dp,0,sizeof(dp));

    for(int prev_combo = 10; prev_combo >= 0; prev_combo--){
      for(int prev_action = 4; prev_action >= 0; prev_action--){
        for(int prev_stability = 10; prev_stability >= 0; prev_stability--){
          dp[len][prev_combo][100][prev_stability][prev_action] = 1.0;
        }
      }
    }

    //dp[note_i][prev_combo][prev_score][prev_stability][prev_action]
    for(int note_i = len - 1; note_i >= 0; note_i--){
      if(notes[note_i] == 0){
        for(int prev_score = 100; prev_score >= 0; prev_score--){
          for(int prev_combo = 10; prev_combo >= 0; prev_combo--){
            for(int prev_stability = 10; prev_stability >= 0; prev_stability--){
              for(int prev_action = 4; prev_action >= 0; prev_action--){
                dp[note_i][prev_combo][prev_score][prev_stability][prev_action]
                  = dp[note_i + 1][prev_combo][prev_score][10][4];
              }
            }
          }
        }
      }              
      else if(notes[note_i] > 0){
        int offset = (notes[note_i] == 1 ? 0 : 2);
        for(int prev_score = 100; prev_score >= 0; prev_score--){
          for(int prev_combo = 10; prev_combo >= 0; prev_combo--){
            int added = (A + B * prev_combo) / 100;

            for(int prev_stability = 10; prev_stability >= 0; prev_stability--){
              for(int prev_action = 3; prev_action >= 0; prev_action--){
                dp[note_i][prev_combo][prev_score][prev_stability][prev_action] 
                  = dp[note_i + 1][0][prev_score][10][4];

                int st0 = max(0,(stability[prev_action][offset + 0] - 10) * 10 + prev_stability * 10);
                int st1 = max(0,(stability[prev_action][offset + 1] - 10) * 10 + prev_stability * 10);
                
                double precision0 = (double)st0/100.0;
                double precision1 = (double)st1/100.0;


                //bang
                dp[note_i][prev_combo][prev_score][prev_stability][prev_action] 
                  = max(dp[note_i][prev_combo][prev_score][prev_stability][prev_action] ,
                        dp[note_i + 1][min(10,prev_combo + 1)][min(100,prev_score + added)][st0 / 10][offset + 0] * precision0
                        + dp[note_i + 1][0][prev_score][st0 / 10][offset + 0] * (1.0 - precision0));

                dp[note_i][prev_combo][prev_score][prev_stability][prev_action] 
                  = max(dp[note_i][prev_combo][prev_score][prev_stability][prev_action],
                        dp[note_i + 1][min(10,prev_combo + 1)][min(100,prev_score + added)][st1 / 10][offset + 1] * precision1
                        + dp[note_i + 1][0][prev_score][st1 / 10][offset + 1] * (1.0 - precision1));
                
              }

              //ignore
              dp[note_i][prev_combo][prev_score][prev_stability][4]
                      = max(dp[note_i + 1][0][prev_score][10][4],
                            max(dp[note_i + 1][min(10,prev_combo + 1)][min(100,prev_score + added)][10][offset + 0],
                                dp[note_i + 1][min(10,prev_combo + 1)][min(100,prev_score + added)][10][offset + 1]));

            }
          }
        }
      }
    }
    printf("%.6lf\n",dp[0][0][0][10][4]);
  }
  over:;

}
accuracy: 1
time_ms: 4960
memory_kb: 49444
final_rank: 8

code_snippet: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
#include <cctype>
#include <utility>
 
using namespace std;
 
typedef long long ll;
typedef pair <int,int> P;
typedef pair <int,P > PP;
 
int tx[] = {0,1,0,-1};
int ty[] = {-1,0,1,0};
 
static const double EPS = 1e-8;

double dp[101][11][101][11][5];//dp[note_i][prev_combo][prev_score][prev_stability][prev_action]

int main(){
  while(true){
    //lt rt lk rk
    int stability[4][4];
    for(int i = 0; i < 4; i++){
      int count = 0;
      for(int j = 0; j < 4; j++){
        scanf("%d",&stability[i][j]);
        if(i == 0 && stability[i][j] == -1){
          count++;
        }
      }
      if(count >= 4) goto over;
    }
    int len;
    scanf("%d",&len);
    
    int notes[101];
    
    //0:none 1:t 2:k
    for(int note_i = 0; note_i < len; note_i++){
      scanf("%d",&notes[note_i]);
    }
    int A,B;
    scanf("%d %d",&A,&B);
    
    memset(dp,0,sizeof(dp));

    for(int prev_combo = 10; prev_combo >= 0; prev_combo--){
      for(int prev_action = 4; prev_action >= 0; prev_action--){
        for(int prev_stability = 10; prev_stability >= 0; prev_stability--){
          dp[len][prev_combo][100][prev_stability][prev_action] = 1.0;
        }
      }
    }

    //dp[note_i][prev_combo][prev_score][prev_stability][prev_action]
    for(int note_i = len - 1; note_i >= 0; note_i--){
      if(notes[note_i] == 0){
        for(int prev_score = 100; prev_score >= 0; prev_score--){
          for(int prev_combo = 10; prev_combo >= 0; prev_combo--){
            for(int prev_stability = 10; prev_stability >= 0; prev_stability--){
              for(int prev_action = 4; prev_action >= 0; prev_action--){
                dp[note_i][prev_combo][prev_score][prev_stability][prev_action]
                  = dp[note_i + 1][prev_combo][prev_score][10][4];
              }
            }
          }
        }
      }              
      else if(notes[note_i] > 0){
        int offset = (notes[note_i] == 1 ? 0 : 2);
        for(int prev_score = 100; prev_score >= 0; prev_score--){
          for(int prev_combo = 10; prev_combo >= 0; prev_combo--){
            int added = (A + B * prev_combo) / 100;

            for(int prev_stability = 10; prev_stability >= 0; prev_stability--){
              for(int prev_action = 3; prev_action >= 0; prev_action--){
                dp[note_i][prev_combo][prev_score][prev_stability][prev_action] 
                  = dp[note_i + 1][0][prev_score][10][4];

                int st0 = max(0,(stability[prev_action][offset + 0] - 10) * 10 + prev_stability * 10);
                int st1 = max(0,(stability[prev_action][offset + 1] - 10) * 10 + prev_stability * 10);
                
                double precision0 = (double)st0/100.0;
                double precision1 = (double)st1/100.0;


                //bang
                dp[note_i][prev_combo][prev_score][prev_stability][prev_action] 
                  = max(dp[note_i][prev_combo][prev_score][prev_stability][prev_action] ,
                        dp[note_i + 1][min(10,prev_combo + 1)][min(100,prev_score + added)][st0 / 10][offset + 0] * precision0
                        + dp[note_i + 1][0][prev_score][st0 / 10][offset + 0] * (1.0 - precision0));

                dp[note_i][prev_combo][prev_score][prev_stability][prev_action] 
                  = max(dp[note_i][prev_combo][prev_score][prev_stability][prev_action],
                        dp[note_i + 1][min(10,prev_combo + 1)][min(100,prev_score + added)][st1 / 10][offset + 1] * precision1
                        + dp[note_i + 1][0][prev_score][st1 / 10][offset + 1] * (1.0 - precision1));
                
              }

              dp[note_i][prev_combo][prev_score][prev_stability][4] = dp[note_i + 1][0][prev_score][10][4];
              dp[note_i][prev_combo][prev_score][prev_stability][4]
                      = max(dp[note_i][prev_combo][prev_score][prev_stability][4],
                            max(dp[note_i + 1][min(10,prev_combo + 1)][min(100,prev_score + added)][10][offset + 0],
                                dp[note_i + 1][min(10,prev_combo + 1)][min(100,prev_score + added)][10][offset + 1]));

            }
          }
        }
      }
    }
    printf("%.6lf\n",dp[0][0][0][10][4]);
  }
  over:;

}
accuracy: 1
time_ms: 5060
memory_kb: 49444
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>
#include <tuple>
#include <iterator>
#include <bitset>
#include <random>
#include <assert.h>
#include <unordered_map>
#include <array>
#include <ctime>

#ifdef _MSC_VER
#include <agents.h>
#endif

#define FOR(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define X first
#define Y second
#define MP make_pair
#define umap unordered_map

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> P;
typedef unsigned int uint;

//map<tuple<int, int, int, int, int>, double> dp;
//int table[4][4];
//int v[101];
//
//double EPS = 1e-9;
//
//int L, A, B;
//double rec(int n, int acc, int prv, int comb, int pnt){
//	if (n == L) return pnt == 100;
//
//	auto t = make_tuple(n, acc, prv, comb, pnt);
//	if (dp.count(t)) return dp[t];
//	double &res = dp[t];
//
//	res = 0;
//
//	res = rec(n + 1, 0, 4, v[n] ? 0 : comb, pnt);
//	if(v[n] != 0) for (int i = 0; i < 4; ++i){
//		if (v[n] == 2 && i < 2) continue;
//		if (v[n] == 1 && i >= 2) continue;
//		int ip;
//		if (prv == 4) ip = 10;
//		else ip = max(0, (table[prv][i] - 10) + acc);
//		double p = ip / 10.;
//
//		double tmp = 0;
//		if(p > EPS) tmp += p*rec(n + 1, ip, i, comb+1, min(100, pnt+A+B*min(comb, 10)));
//		if(1-p > EPS) tmp += (1 - p)*rec(n + 1, ip, i, 0, pnt);
//		res = max(res, tmp);
//	}
//
//	return res;
//}

int table[4][4];
int v[101];

double EPS = 1e-9;
int L, A, B;

double dp[2][11][5][11][101]; // i, prv_acc, prv_pos, combo, point

int main(){
	cout.setf(ios::fixed);
	cout.precision(10);
	while (1){
		rep(i, 4) rep(j, 4){
			cin >> table[i][j];
			if (table[i][j] < 0) goto end;
		}
		cin >> L;
		rep(i, L) cin >> v[i];
		cin >> A >> B;
		A /= 100, B /= 100;

		int cur = 0, nxt = 1;
		rep(i, 11) rep(j, 5) rep(k, 11) rep(l, 101) dp[cur][i][j][k][l] = l == 100;
		for (int n = L - 1; n >= 0; --n){
			rep(acc, 11) rep(prv, 5) rep(comb, 11) rep(pnt, 101){
				double &res = dp[nxt][acc][prv][comb][pnt];
				res = 0;
				
				res = dp[cur][0][4][v[n] ? 0 : comb][pnt];
				if(v[n] != 0) for (int i = 0; i < 4; ++i){
					if (v[n] == 2 && i < 2) continue;
					if (v[n] == 1 && i >= 2) continue;
					int ip;
					if (prv == 4) ip = 10;
					else ip = max(0, (table[prv][i] - 10) + acc);
					double p = ip * .1;
				
					double tmp = 0;
					tmp += p*dp[cur][ip][i][min(10, comb+1)][min(100, pnt+A+B*min(comb, 10))];
					tmp += (1 - p)*dp[cur][ip][i][0][pnt];
					res = max(res, tmp);
				}
			}
			swap(cur, nxt);
		}
		cout << dp[cur][0][4][0][0] << endl;
	}

end:
	return 0;
}
accuracy: 1
time_ms: 6370
memory_kb: 2192
final_rank: 2

code_snippet: #include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<(b)?(a=b,1):0)
#define chmin(a,b) (a>(b)?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
const int INF = 1<<29;
const double EPS = 1e-8;
const double PI = acos(-1);
typedef pair<int,int> pii;
typedef long long ll;

int stability[4][4];
int s[100];
double dp[101][101][11][11][3];

bool solve() {
  REP(i,4) {
    REP(j,4) {
      cin >> stability[i][j];
      if (stability[i][j] == -1) return 0;
    }
  }
  int L;
  cin >> L;
  REP(i,L) cin >> s[i];
  int A, B;
  cin >> A >> B;
  A/=100;B/=100;

  REP(i,L+1)REP(j,101)REP(k,11)REP(l,11)REP(m,3)dp[i][j][k][l][m] = 0;
  REP(k,11) REP(l,11) REP(m,3) dp[L][100][k][l][m] = 1;

  for (int i=L-1; i>=0; --i) {
    REP(j,101) {
      REP(k,11) {
        REP(l,11) {
          REP(m,3) {
            if (m==2&&k!=10) continue;
            if (i==0&&m!=2) continue;
            if (i&&s[i-1]==0&&m!=2) continue;
            double &DP = dp[i][j][k][l][m];
            if (s[i] == 0) {
              chmax(DP, dp[i+1][j][10][l][2]);
            } else {
              int score = A + B*l;
              REP(n,2) {
                int stab;
                if (m == 2) {
                  stab = 10;
                } else {
                  int cur = (s[i]-1)*2 + n;
                  int pre = (s[i-1]-1)*2 + m;
                  stab = max(0, stability[pre][cur]-10+k);
                }
                double prob = 0.1*stab;
                chmax(DP, dp[i+1][min(j+score,100)][stab][min(l+1,10)][n]*prob + dp[i+1][j][stab][0][n]*(1-prob));
              }
              chmax(DP, dp[i+1][j][10][0][2]);
            }
          }
        }
      }
    }
  }
  double ans = dp[0][0][10][0][2];

  printf("%.10f\n", ans);
  return 1;
}

int main() {
  while(solve());

}
accuracy: 1
time_ms: 3520
memory_kb: 30112
final_rank: 3

code_snippet: #include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<(b)?(a=b,1):0)
#define chmin(a,b) (a>(b)?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
const int INF = 1<<29;
const double EPS = 1e-8;
const double PI = acos(-1);
typedef pair<int,int> pii;
typedef long long ll;

int stability[4][4];
int s[100];
double dp[101][101][11][11][3];

bool solve() {
  REP(i,4) {
    REP(j,4) {
      cin >> stability[i][j];
      if (stability[i][j] == -1) return 0;
    }
  }
  int L;
  cin >> L;
  REP(i,L) cin >> s[i];
  int A, B;
  cin >> A >> B;
  A/=100;B/=100;

  REP(i,L+1)REP(j,101)REP(k,11)REP(l,11)REP(m,3)dp[i][j][k][l][m] = 0;
  REP(k,11) REP(l,11) REP(m,3) dp[L][100][k][l][m] = 1;

  for (int i=L-1; i>=0; --i) {
    REP(j,101) {
      REP(k,11) {
        REP(l,11) {
          REP(m,3) {
            if (m==2&&k!=10) continue;
            if (i==0&&m!=2) continue;
            if (i&&s[i-1]==0&&m!=2) continue;
            double &DP = dp[i][j][k][l][m];
            if (s[i] == 0) {
              chmax(DP, dp[i+1][j][10][l][2]);
            } else {
              int score = A + B*l;
              REP(n,2) {
                int stab;
                if (m == 2) {
                  stab = 10;
                } else {
                  int cur = (s[i]-1)*2 + n;
                  int pre = (s[i-1]-1)*2 + m;
                  stab = max(0, stability[pre][cur]-10+k);
                }
                double prob = 0.1*stab;
                chmax(DP, dp[i+1][min(j+score,100)][stab][min(l+1,10)][n]*prob + dp[i+1][j][stab][0][2]*(1-prob));
              }
              chmax(DP, dp[i+1][j][10][0][2]);
            }
          }
        }
      }
    }
  }
  double ans = dp[0][0][10][0][2];

  printf("%.10f\n", ans);
  return 1;
}

int main() {
  while(solve());

}
accuracy: 0.2857142857142857
time_ms: 360
memory_kb: 30112
final_rank: 13

code_snippet: #include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cassert>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
#define chmax(a,b) (a<(b)?(a=b,1):0)
#define chmin(a,b) (a>(b)?(a=b,1):0)
#define valid(y,x,h,w) (0<=y&&y<h&&0<=x&&x<w)
const int INF = 1<<29;
const double EPS = 1e-8;
const double PI = acos(-1);
typedef pair<int,int> pii;
typedef long long ll;

int stability[4][4];
int s[100];
double dp[101][101][11][11][3];

bool solve() {
  REP(i,4) {
    REP(j,4) {
      cin >> stability[i][j];
      if (stability[i][j] == -1) return 0;
    }
  }
  int L;
  cin >> L;
  REP(i,L) cin >> s[i];
  int A, B;
  cin >> A >> B;
  A/=100;B/=100;

  REP(i,L+1)REP(j,101)REP(k,11)REP(l,11)REP(m,3)dp[i][j][k][l][m] = 0;
  REP(k,11) REP(l,11) REP(m,3) dp[L][100][k][l][m] = 1;

  for (int i=L-1; i>=0; --i) {
    REP(j,101) {
      REP(k,11) {
        REP(l,11) {
          REP(m,3) {
            if (m==2&&k!=10) continue;
            if (i==0&&m!=2) continue;
            if (i&&s[i-1]==0&&m!=2) continue;
            double &DP = dp[i][j][k][l][m];
            if (s[i] == 0) {
              chmax(DP, dp[i+1][j][10][l][2]);
            } else {
              int score = A + B*l;
              REP(n,2) {
                int stab;
                if (m == 2) {
                  stab = 10;
                } else {
                  int cur = (s[i]-1)*2 + n;
                  int pre = (s[i-1]-1)*2 + m;
                  stab = max(0, stability[pre][cur]-10+k);
                }
                double prob = 0.1*stab;
                chmax(DP, dp[i+1][min(j+score,100)][stab][min(l+1,10)][n]*prob + dp[i+1][j][10][0][2]*(1-prob));
              }
              chmax(DP, dp[i+1][j][10][0][2]);
            }
          }
        }
      }
    }
  }
  double ans = dp[0][0][10][0][2];

  printf("%.10f\n", ans);
  return 1;
}

int main() {
  while(solve());

}
accuracy: 0.2857142857142857
time_ms: 360
memory_kb: 30112
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int main(){
    while(true){
        int M[5][5];

        for(int i = 0; i < 4; i++)
        for(int j = 0; j < 4; j++)
            cin >> M[i][j];
        for(int i = 0; i < 5; i++){
            M[4][i] = M[i][4] = 10;
        }

        if(M[0][0] < 0) break;

        int L;
        cin >> L;
        vector<int> S(L);

        for(int i = 0; i < L; i++){
            cin >> S[i];
        }

        int A, B;
        cin >> A >> B;
        A /= 100, B /= 100;

        static double dp[101][11][101][5][11] = {}; // time, before precision, score, before, combo
        memset(dp, 0, sizeof dp);

        for(int i = 0; i <= 10; i++)
        for(int b = 0; b < 5; b++)
        for(int c = 0; c <= 10; c++)
            dp[L][i][100][b][c] = 1.0;

        for(int t = L - 1; t >= 0; t--)
        for(int p = 0; p <= 10; p++)
        for(int s = 0; s <= 100; s++)
        for(int c = 0; c <= 10; c++)
        for(int y = 0; y < 5; y++) // t - 1
        for(int x = 0; x < 5; x++){ // t
            if(S[t] != 0 && (x / 2) != S[t] - 1 && x != 4) continue;
            if(S[t] == 0 && x != 4) continue;
            int np = ((x == 4 || S[t] == 0) ? 10 : max(0, (M[y][x] - 10) + p));
            int ns = ((x == 4 || S[t] == 0) ? s : min(100, s + A + B * c));
            int nc = (S[t] == 0 ? c : x == 4 ? 0 : min(10, c + 1));

            dp[t][p][s][y][c] = max(dp[t][p][s][y][c],
                                 np / 10.0 * dp[t + 1][np][ns][x][nc] +
                                 (10.0 - np) / 10.0 * dp[t + 1][ns][s][x][0]);
        }

        printf("%.12f\n",  dp[0][10][0][4][0]);
    }
}
accuracy: 0.14285714285714285
time_ms: 70
memory_kb: 49436
final_rank: 19

code_snippet: #include <iostream>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int main(){
    while(true){
        int M[5][5];

        for(int i = 0; i < 4; i++)
        for(int j = 0; j < 4; j++)
            cin >> M[i][j];
        for(int i = 0; i < 5; i++){
            M[4][i] = M[i][4] = 10;
        }

        if(M[0][0] < 0) break;

        int L;
        cin >> L;
        vector<int> S(L);

        for(int i = 0; i < L; i++){
            cin >> S[i];
        }

        int A, B;
        cin >> A >> B;
        A /= 100, B /= 100;

        static double dp[101][11][101][5][11] = {}; // time, before precision, score, before, combo
        memset(dp, 0, sizeof dp);

        for(int i = 0; i <= 10; i++)
        for(int b = 0; b < 5; b++)
        for(int c = 0; c <= 10; c++)
            dp[L][i][100][b][c] = 1.0;

        for(int t = L - 1; t >= 0; t--)
        for(int p = 0; p <= 10; p++)
        for(int s = 0; s <= 100; s++)
        for(int c = 0; c <= 10; c++)
        for(int y = 0; y < 5; y++) // t - 1
        for(int x = 0; x < 5; x++){ // t
            if(S[t] != 0 && (x / 2) != S[t] - 1 && x != 4) continue;
            if(S[t] == 0 && x != 4) continue;
            int np = ((x == 4 || S[t] == 0) ? 10 : max(0, (M[y][x] - 10) + p));
            int ns = ((x == 4 || S[t] == 0) ? s : min(100, s + A + B * c));
            int nc = (S[t] == 0 ? c : x == 4 ? 0 : min(10, c + 1));

            dp[t][p][s][y][c] = max(dp[t][p][s][y][c],
                                 np / 10.0 * dp[t + 1][np][ns][x][nc] +
                                 (10.0 - np) / 10.0 * dp[t + 1][10][s][4][0]);
        }

        printf("%.12f\n",  dp[0][10][0][4][0]);
    }
}
accuracy: 0.2857142857142857
time_ms: 1300
memory_kb: 49436
final_rank: 16

code_snippet: #include <iostream>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int main(){
    while(true){
        int M[5][5];

        for(int i = 0; i < 4; i++)
        for(int j = 0; j < 4; j++)
            cin >> M[i][j];
        for(int i = 0; i < 5; i++){
            M[4][i] = M[i][4] = 10;;
        }

        if(M[0][0] < 0) break;

        int L;
        cin >> L;
        vector<int> S(L);

        for(int i = 0; i < L; i++){
            cin >> S[i];
        }

        int A, B;
        cin >> A >> B;
        A /= 100, B /= 100;

        static double dp[101][11][101][5][11] = {}; // time, before precision, score, before, combo
        memset(dp, 0, sizeof dp);

        for(int i = 0; i <= 10; i++)
        for(int b = 0; b < 5; b++)
        for(int c = 0; c <= 10; c++)
            dp[L][i][100][b][c] = 1.0;

        for(int t = L - 1; t >= 0; t--)
        for(int p = 0; p <= 10; p++)
        for(int s = 0; s <= 100; s++)
        for(int c = 0; c <= 10; c++)
        for(int y = 0; y < 5; y++) // t - 1
        for(int x = 0; x < 5; x++){ // t
            if(S[t] != 0 && (x / 2) != S[t] - 1 && x != 4) continue;
            int np = ((x == 4 || S[t] == 0) ? 10 : max(0, (M[y][x] - 10) + p));
            int ns = ((x == 4 || S[t] == 0) ? s : min(100, s + A + B * c));
            int nc = (S[t] == 0 ? c : x == 4 ? 0 : min(10, c + 1));

            dp[t][p][s][y][c] = max(dp[t][p][s][y][c],
                                 np / 10.0 * dp[t + 1][np][ns][x][nc] +
                                 (10.0 - np) / 10.0 * dp[t + 1][10][s][4][0]);
        }

        printf("%.12f\n",  dp[0][10][0][4][0]);
    }
}
accuracy: 0.2857142857142857
time_ms: 1420
memory_kb: 49436
final_rank: 17

code_snippet: #include <cstdio>
#include <algorithm>
using namespace std;

double dp[101][101][11][11][5];
int stb[16], s[101];
int L, A, B;

/*
prv
	0: 左トン
	1: 右トン
	2: 左コツ
	3: 右コツ
	4: none
*/
double dfs(int len, int scr, int cmb, int prc, int prv){
	cmb = min(cmb, 10);
	scr = min(scr, 100);

	double &ret = dp[len][scr][cmb][prc][prv];
	if(ret < 0.0){
		if(scr >= 100){
			ret = 1.0;
		}
		else if(len == L){
			ret = 0.0;
		}
		else if(s[len] == 0){
			ret = dfs(len + 1, scr, cmb, 10, 4);
		}
		else if(prv == 4){
			ret = dfs(len + 1, scr, 0, 10, 4);
			for(int k = -2; k <= -1; ++k){
				ret = max(ret, dfs(len + 1, scr + A + B * cmb, cmb + 1, 10, s[len] * 2 + k));
			}
		}
		else{
			ret = dfs(len + 1, scr, 0, 10, 4);
			for(int k = -2; k <= -1; ++k){
				int nxt = s[len] * 2 + k;
				int npc = max(0, stb[prv * 4 + nxt] - 10 + prc);
				double ps = dfs(len + 1, scr + A + B * cmb, cmb + 1, npc, nxt);
				double pf = dfs(len + 1, scr, 0, npc, nxt);
				ret = max(ret, 0.1 * (npc * ps + (10 - npc) * pf));
			}
		}
	}

	return ret;
}


int main(){
	while(1){
		for(int i = 0; i < 16; ++i){
			if(scanf("%d", &stb[i]) != 1){ return 0; }
		}
		scanf("%d", &L);
		for(int i = 0; i < L; ++i){
			scanf("%d", &s[i]);
		}
		scanf("%d%d", &A, &B);
		A /= 100;
		B /= 100;

		fill(****dp, ****dp + sizeof(dp) / sizeof(double), -1.0);

		printf("%f\n", dfs(0, 0, 0, 10, 4));
	}
}
accuracy: 1
time_ms: 2460
memory_kb: 49284
final_rank: 6

code_snippet: #include <cstdio>
#include <algorithm>
using namespace std;

double dp[101][101][11][11][5];
int stb[16], s[101];
int L, A, B;

/*
prv
	0: 左トン
	1: 右トン
	2: 左コツ
	3: 右コツ
	4: fail
*/
double dfs(int len, int scr, int cmb, int prc, int prv){
	cmb = min(cmb, 10);
	scr = min(scr, 100);
	double &ret = dp[len][scr][cmb][prc][prv];
	if(ret < 0.0){
		if(scr >= 100){
			ret = 1.0;
		}
		else if(len == L){
			ret = 0.0;
		}
		else if(s[len] == 0){
			ret = dfs(len + 1, scr, cmb, 10, 4);
		}
		else if(prv == 4){
			for(int k = -2; k <= -1; ++k){
				ret = max(ret, dfs(len + 1, scr + A + B * cmb, cmb + 1, 10, s[len] * 2 + k));
			}
		}
		else{
			ret = dfs(len + 1, scr, 0, 10, 4);
			for(int k = -2; k <= -1; ++k){
				int nxt = s[len] * 2 + k;
				int npc = max(0, stb[prv * 4 + nxt] - 10 + prc);
				double ps = dfs(len + 1, scr + A + B * cmb, cmb + 1, npc, nxt);
				double pf = dfs(len + 1, scr, 0, npc, nxt);
				ret = max(ret, 0.1 * (npc * ps + (10 - npc) * pf));
			}
		}
	}

	return ret;
}


int main(){
	while(1){
		for(int i = 0; i < 16; ++i){
			if(scanf("%d", &stb[i]) != 1){ return 0; }
		}
		scanf("%d", &L);
		for(int i = 0; i < L; ++i){
			scanf("%d", &s[i]);
		}
		scanf("%d%d", &A, &B);
		A /= 100;
		B /= 100;

		fill(****dp, ****dp + sizeof(dp) / sizeof(double), -1.0);

		printf("%f\n", dfs(0, 0, 0, 10, 4));
	}
}
accuracy: 0.2857142857142857
time_ms: 180
memory_kb: 49284
final_rank: 15

code_snippet: #include <cstring>
#include <queue>
#include <cstdio>
inline int getInt(){ int s; scanf("%d", &s); return s; }

#define REP(i,n) for(int i=0; i<(int)(n); i++)

#include <set>

using namespace std;

int safe[4][4];
int n;
// [pos][prev][antei][combo][point]
double dp[101][5][11][11][101];

vector<int> s;
int a, b;

double solve(int pos, int prev, int antei, int combo, int point){
  /*
  printf("pos: %d, prev: %d, antei: %d, combo: %d, point: %d\n",
         pos, prev, antei, combo, point);
  */
  if(pos == n){
    if(point == 100) return 1.0;
    else return 0.0;
  }

  double &ret = dp[pos][prev][antei][combo][point];
  if(ret >= -1.0) return ret;
  ret = 0.0;

  const int note = s[pos] - 1;

  if(note == -1){
    ret = solve(pos + 1, 4, 10, combo, point);
  }else{
    REP(h,2){
      const int hh = note * 2 + h;
      int aa = 0;
      if(prev == 4){
        aa = 10;
      }else{
        aa = max(0, antei + safe[prev][hh] - 10);
      }
      if(aa){
        ret = max(ret,
                  (aa / 10.0) * solve(pos + 1, hh, aa, min(10, combo + 1), min(100, point + a + b * combo)) +
                  (1.0 - aa / 10.0) * solve(pos + 1, hh, aa, 0, point));
      }
    }
    ret = max(ret, solve(pos + 1, 4, 10, 0, point));
  }

  return ret;
}

int main(){
  while(true){
    REP(i,4) safe[0][i] = getInt();

    if(safe[0][0] + safe[0][1] +
       safe[0][2] + safe[0][3] == -4)
      break;

    REP(i,3) REP(j,4)
      safe[i + 1][j] = getInt();

    const int l = getInt();
    vector<int> s(l);

    REP(i,l) s[i] = getInt();
    ::a = getInt() / 100;
    ::b = getInt() / 100;
    ::s = s;
    ::n = l;

    // double dp[101][5][11][11][101];
    REP(i,101) REP(j,5) REP(k,11) REP(l,11) REP(m,101)
      dp[i][j][k][l][m] = -2.0;

    printf("%.8f\n", solve(0, 4, 10, 0, 0));
  }

  return 0;
}
accuracy: 1
time_ms: 1510
memory_kb: 49320
final_rank: 4

code_snippet: #include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <vector>
using namespace std;

typedef vector<double> vec;
typedef vector<vec> vec2;
typedef vector<vec2> vec3;
typedef vector<vec3> vec4;

template<class T> inline void chmax(T& a, T b) { if(b > a) a = b; }

enum { LT, RT, LK, RK, NONE };

int main() {
	for(;;) {
		int acc[4][4];
		for(int i = 0; i < 4; ++i)
			scanf("%d", &acc[0][i]);

		if(acc[0][0] < 0)
			break;

		for(int i = 1; i < 4; ++i)
			for(int j = 0; j < 4; ++j)
				scanf("%d", &acc[i][j]);

		int l;
		scanf("%d", &l);

		vector<int> s(l);
		for(int i = 0; i < l; ++i)
			scanf("%d", &s[i]);

		int a, b;
		scanf("%d %d", &a, &b);
		a /= 100;
		b /= 100;

		vec4 dp(101, vec3(5, vec2(11, vec(11, 0.0))));
		for(int i = 0; i < 5; ++i)
			for(int j = 0; j < 11; ++j)
				for(int k = 0; k < 11; ++k)
					dp[100][i][j][k] = 1.0;

		for(int next = l - 1; next >= 0; --next) {
			vec4 tmp(101, vec3(5, vec2(11, vec(11, 1.0))));
			if(s[next] == 0) {
				for(int sco = 0; sco < 100; ++sco)
					for(int pre = 0; pre < 5; ++pre)
						for(int com = 0; com <= 10; ++com)
							for(int pac = 0; pac <= 10; ++pac)
								tmp[sco][pre][com][pac] = dp[sco][NONE][com][10];
				dp.swap(tmp);
				continue;
			}

			const int start = (s[next] == 1 ? 0 : 2);
			for(int sco = 0; sco < 100; ++sco) {
				for(int pre = 0; pre < 4; ++pre) {
					for(int pac = 0; pac <= 10; ++pac) {
						for(int com = 0; com <= 10; ++com)
							tmp[sco][pre][com][pac] = dp[sco][NONE][0][10];

						for(int i = start; i < start + 2; ++i) {
							const int ac = max(0, (acc[pre][i] - 10) + pac);
							const double p = ac / 10.0;
							for(int com = 0; com <= 10; ++com) {
								const double buf = p * dp[min(100, sco + a + b * min(10, com))][i][min(10, com + 1)][ac] + (1.0 - p) * dp[sco][i][0][ac];
								chmax(tmp[sco][pre][com][pac], buf);
							}
						}
					}
				}

				for(int com = 0; com <= 10; ++com) {
					for(int pac = 0; pac <= 10; ++pac) {
						tmp[sco][NONE][com][pac] = dp[sco][NONE][0][10];
						for(int i = start; i < start + 2; ++i) {
							chmax(tmp[sco][NONE][com][pac], dp[min(100, sco + a + b * min(10, com))][i][min(10, com + 1)][10]);
						}
					}
				}
			}

			dp.swap(tmp);
		}

		printf("%.5lf\n", dp[0][NONE][0][10]);
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 6890
memory_kb: 2456
final_rank: 5