BZOJ4832: [Lydsy1704月赛]抵制克苏恩 (记忆化搜索 + 概率DP)
题意:模拟克苏恩打奴隶战对对方英雄所造成的伤害
题解:因为昨(今)天才写过记忆化搜索 所以这个就是送经验了
1A还冲了个榜 但是我惊奇的发现我数组明明就比数据范围开小了啊???
#include <bits/stdc++.h> using namespace std; int k, a, b, c; double dp[50][8][8][8]; double dfs(int at, int x, int y, int z) { if(dp[at][x][y][z]) return dp[at][x][y][z]; double tmp = 0; double fm = 1.0 * (x + y + z + 1.0); tmp += 1.0 / fm * (dfs(at - 1, x, y, z) + 1.0); if(x) tmp += 1.0 * x / fm * dfs(at - 1, x - 1, y, z); if(y) { if(x + y + z == 7) tmp += 1.0 * y / fm * dfs(at - 1, x + 1, y - 1, z); else tmp += 1.0 * y / fm * dfs(at - 1, x + 1, y - 1, z + 1); } if(z) { if(x + y + z == 7) tmp += 1.0 * z / fm * dfs(at - 1, x, y + 1, z - 1); else tmp += 1.0 * z / fm * dfs(at - 1, x, y + 1, z); } dp[at][x][y][z] = tmp; return tmp; } int main() { int T; scanf("%d", &T); for(int i = 0; i < 8; i++) for(int j = 0; j < 8; j++) { if(i + j > 7) continue; for(int k = 0; k < 8; k++) { if(i + j + k > 7) continue; dp[1][i][j][k] = 1.0 / (i + j + k + 1.0); } } while(T--) { scanf("%d%d%d%d", &k, &a, &b, &c); double ans = dfs(k, a, b, c); printf("%.2lf\n", ans); } return 0; }