結果
| 問題 |
No.463 魔法使いのすごろく🎲
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-12-15 13:28:53 |
| 言語 | Java (openjdk 23) |
| 結果 |
AC
|
| 実行時間 | 221 ms / 2,000 ms |
| コード長 | 2,621 bytes |
| コンパイル時間 | 4,020 ms |
| コンパイル使用メモリ | 87,768 KB |
| 実行使用メモリ | 43,668 KB |
| 最終ジャッジ日時 | 2024-11-30 08:22:21 |
| 合計ジャッジ時間 | 12,246 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 36 |
ソースコード
package yukicoder;
import java.util.*;
public class Q463 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
double[] c = new double[n];
for (int i = 1; i < n - 1; ++i) {
c[i] = sc.nextDouble();
}
// 魔法を使わずにマスi(0<=i<n-1)からn-1まで行くのに必要な回数の期待値
double[] dp1 = new double[n];
// A(Evec+a)=Evec
// (A-E)x=-Aa
double[][] mx = new double[n - 1][n - 1];
for (int i = 0; i < n - 1; ++i) {
double p = 1.0 / m;
for (int j = 1; j <= m; ++j) {
if (i + j < n - 1) {
mx[i][i + j] += p;
} else if (i + j == n - 1) {
continue;
} else {
int pos = (n - 1) - ((i + j) - (n - 1));
mx[i][pos] += p;
}
}
}
double[] v = new double[n - 1];
for (int i = 0; i < n - 1; ++i) {
v[i] = -c[i];
}
v = mul(mx, v);
for (int i = 0; i < n - 1; ++i) {
mx[i][i] -= 1;
}
// [mx]x=vをxについて解きたい.
for (int i = 0; i < n - 1; ++i) {
int pos = i;
while (pos < n - 1 && mx[pos][i] == 0) {
++pos;
}
if (pos == n - 1)
continue;
double[] tmp = mx[i];
mx[i] = mx[pos];
mx[pos] = tmp;
double tmp3 = v[i];
v[i] = v[pos];
v[pos] = tmp3;
double tmp2 = mx[i][i];
for (int j = 0; j < n - 1; ++j) {
mx[i][j] /= tmp2;
}
v[i] /= tmp2;
for (int j = 0; j < n - 1; ++j) {
if (mx[j][i] == 0)
continue;
if (j == i)
continue;
double tmp4 = mx[j][i];
for (int k = 0; k < n - 1; ++k) {
mx[j][k] -= mx[i][k] * tmp4;
}
v[j] -= v[i] * tmp4;
}
}
double[] e = new double[n];
Arrays.fill(e, Double.MAX_VALUE);
e[n - 1] = 0;
outer: for (int i = n - 2; i >= 0; --i) {
double e1 = 0;
for (int j = m; j >= 1; --j) {
if (i + j >= n - 1) {
e[i] = 0;
continue outer;
} else {
e1 += 1.0 / m * (e[i + j] + c[i + j]);
}
}
double e2 = 1L << 60;
for (int j = m; j >= 1; --j) {
e2 = Math.min(e2, v[i + j] + c[i + j]);
}
e[i] = Math.min(e1, e2);
}
System.out.printf("%.20f",e[0]);
}
static void show(double[][] mx) {
int n = mx.length;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
System.out.print(mx[i][j] + " ");
}
System.out.println();
}
}
static double[] mul(double[][] a, double[] v) {
int n = a.length;
double[] ret = new double[n];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
ret[i] += a[i][j] * v[j];
}
}
return ret;
}
static void tr(Object... objects) {
System.out.println(Arrays.deepToString(objects));
}
}