Legends of the Three Kingdoms
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 928 Accepted Submission(s): 148
The players take turns to move in each round of the game: the Monarch moves first, then the Rebel, the Minister,and finally the Traitor. In a player’s turn, if he/she is surviving, he/she must attack a player and the health points of that player will decrease by 1. Note that the dead players cannot attack the other players, and self attacking isnot allowed.
When one of the following events happens, the game ends immediately.
∙ Both of the Rebel and the Traitor are dead: The Monarch and the Minister win the game, no matter theminister is surviving or not.
∙ The Monarch is dead: If the Traitor is surviving and all the other players are dead, the Traitor wins; otherwisethe Rebel wins, no matter he/she is surviving or not.
The players have the following common knowledge on their strategies.
∙ The Monarch and the Minister never attack with each other.
∙ After attacking the chosen player, the probability of winning the game is maximized.
∙ If there are multiple players to choose, such that the winning probability is the same and maximized, all theseplayers will be chosen by equal chance.
Your task is to calculate the winning probability of each player.
題意:
給你四個人a,c,b,d的初始血量h1,h2,h3,h4(<40)
a,b,c,d(注意和輸入不一樣)四個人輪流操作,每個人可以任意選擇一個人並砍他一下(使他血量-1)。
勝負規則如下:(據說是三國殺,然而我並木有玩過)
1、如果b和d血量爲0,則a,c勝利(他倆是一夥的)
2、如果a血量爲0時,bc血量都爲0,則d勝利
3、如果a血量爲0時,bc血量不都爲0,則b勝利
4、a和c不會相互攻擊
5、每個人都足夠聰明,當輪到某個人攻擊時,他會選擇攻擊那個使自己獲勝概率最大的人x,如果有多個人相同,那麼他等可能的攻擊這些人。
問你最後ac、b、d獲勝的概率。
思路:
直接記憶化搜索!!!
dp[i][a][b][c][d][x]表示i獲勝、四個人血量分別爲abcd、下一步該x操作的最大概率。
依次枚舉攻擊每個人,取一個最大的獲勝概率,記錄最大的獲勝概率相同的總數,討論每種情況。
注意,vis數組要全局初始化。
代碼:
//#include<bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<queue>
#include<vector>
#include<map>
#define ll long long
#define inf 0x3f3f3f3f
#define mst(head,x,n) memset(head+1,x,n*sizeof(head[0]))
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
using namespace std;
const int maxn=4e2+5;
//const double pi=acos(-1.0);
const double eps=1e-13;
//const ll mo=1e9+7;
double dp[3][40][40][40][40][4];
bool vis[40][40][40][40][4];
int a[5];
template <typename T>
inline void read(T &X)
{
X=0;int w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
if(w) X=-X;
}
void dfs(int a,int b,int c,int d,int x){
if(vis[a][b][c][d][x]) return ;
vis[a][b][c][d][x]=1;
if(!b&&!d){
dp[0][a][b][c][d][x]=1.0;
dp[1][a][b][c][d][x]=0.0;
dp[2][a][b][c][d][x]=0.0;
return ;
}
if(!a){
if(!b&&!c){
dp[2][a][b][c][d][x]=1.0;
dp[0][a][b][c][d][x]=0.0;
dp[1][a][b][c][d][x]=0.0;
}
else {
dp[1][a][b][c][d][x]=1.0;
dp[0][a][b][c][d][x]=0.0;
dp[2][a][b][c][d][x]=0.0;
}
return ;
}
if(x==0&&a==0||x==1&&b==0||x==2&&c==0||x==3&&d==0){
dfs(a,b,c,d,(x+1)%4);
rep(j,0,2)
dp[j][a][b][c][d][x]=dp[j][a][b][c][d][(x+1)%4];
return ;
}
int xx=0;
int e=(x+1)%4;
double d1=0.0;
double d2=0.0;
double d3=0;
if(x==0||x==2){
double t=-1.0;
if(b>0) {
dfs(a,b-1,c,d,e);
double tmp=dp[0][a][b-1][c][d][e];
if(tmp-t>eps){
xx=1;
t=tmp;
d1=dp[0][a][b-1][c][d][e];
d2=dp[1][a][b-1][c][d][e];
d3=dp[2][a][b-1][c][d][e];
}
else if(fabs(tmp-t)<eps){
xx++;
d1+=dp[0][a][b-1][c][d][e];
d2+=dp[1][a][b-1][c][d][e];
d3+=dp[2][a][b-1][c][d][e];
}
}
if(d>0) {
dfs(a,b,c,d-1,e);
double tmp=dp[0][a][b][c][d-1][e];
if(tmp-t>eps){
xx=1;
t=tmp;
d1=dp[0][a][b][c][d-1][e];
d2=dp[1][a][b][c][d-1][e];
d3=dp[2][a][b][c][d-1][e];
}
else if(fabs(tmp-t)<eps){
xx++;
d1+=dp[0][a][b][c][d-1][e];
d2+=dp[1][a][b][c][d-1][e];
d3+=dp[2][a][b][c][d-1][e];
}
}
}
if(x==1){
double t=-1.0;
if(a>0) {
dfs(a-1,b,c,d,e);
double tmp=dp[1][a-1][b][c][d][e];
if(tmp-t>eps){
xx=1;
t=tmp;
d1=dp[0][a-1][b][c][d][e];
d2=dp[1][a-1][b][c][d][e];
d3=dp[2][a-1][b][c][d][e];
}
else if(fabs(tmp-t)<eps){
xx++;
d1+=dp[0][a-1][b][c][d][e];
d2+=dp[1][a-1][b][c][d][e];
d3+=dp[2][a-1][b][c][d][e];
}
}
if(c>0) {
dfs(a,b,c-1,d,e);
double tmp=dp[1][a][b][c-1][d][e];
if(tmp-t>eps){
xx=1;
t=tmp;
d1=dp[0][a][b][c-1][d][e];
d2=dp[1][a][b][c-1][d][e];
d3=dp[2][a][b][c-1][d][e];
}
else if(fabs(tmp-t)<eps){
xx++;
d1+=dp[0][a][b][c-1][d][e];
d2+=dp[1][a][b][c-1][d][e];
d3+=dp[2][a][b][c-1][d][e];
}
}
if(d>0) {
dfs(a,b,c,d-1,e);
double tmp=dp[1][a][b][c][d-1][e];
if(tmp-t>eps){
xx=1;
t=tmp;
d1=dp[0][a][b][c][d-1][e];
d2=dp[1][a][b][c][d-1][e];
d3=dp[2][a][b][c][d-1][e];
}
else if(fabs(tmp-t)<eps){
xx++;
d1+=dp[0][a][b][c][d-1][e];
d2+=dp[1][a][b][c][d-1][e];
d3+=dp[2][a][b][c][d-1][e];
}
}
}
if(x==3){
double t=-1.0;
if(a>0) {
dfs(a-1,b,c,d,e);
double tmp=dp[2][a-1][b][c][d][e];
if(tmp-t>eps){
xx=1;
t=tmp;
d1=dp[0][a-1][b][c][d][e];
d2=dp[1][a-1][b][c][d][e];
d3=dp[2][a-1][b][c][d][e];
}
else if(fabs(tmp-t)<eps){
xx++;
d1+=dp[0][a-1][b][c][d][e];
d2+=dp[1][a-1][b][c][d][e];
d3+=dp[2][a-1][b][c][d][e];
}
}
if(c>0) {
dfs(a,b,c-1,d,e);
double tmp=dp[2][a][b][c-1][d][e];
if(tmp-t>eps){
xx=1;
t=tmp;
d1=dp[0][a][b][c-1][d][e];
d2=dp[1][a][b][c-1][d][e];
d3=dp[2][a][b][c-1][d][e];
}
else if(fabs(tmp-t)<eps){
xx++;
d1+=dp[0][a][b][c-1][d][e];
d2+=dp[1][a][b][c-1][d][e];
d3+=dp[2][a][b][c-1][d][e];
}
}
if(b>0) {
dfs(a,b-1,c,d,e);
double tmp=dp[2][a][b-1][c][d][e];
if(tmp-t>eps){
xx=1;
t=tmp;
d1=dp[0][a][b-1][c][d][e];
d2=dp[1][a][b-1][c][d][e];
d3=dp[2][a][b-1][c][d][e];
}
else if(fabs(tmp-t)<eps){
xx++;
d1+=dp[0][a][b-1][c][d][e];
d2+=dp[1][a][b-1][c][d][e];
d3+=dp[2][a][b-1][c][d][e];
}
}
}
dp[0][a][b][c][d][x]=d1/xx;
dp[1][a][b][c][d][x]=d2/xx;
dp[2][a][b][c][d][x]=d3/xx;
}
int main(){
int T,cas=1;
mst(a,0,4);
read(T);
while(T--){
rep(i,1,4) read(a[i]);
swap(a[2],a[3]);
dfs(a[1],a[2],a[3],a[4],0);
printf("%.6lf %.6lf %.6lf\n",dp[0][a[1]][a[2]][a[3]][a[4]][0],dp[1][a[1]][a[2]][a[3]][a[4]][0],dp[2][a[1]][a[2]][a[3]][a[4]][0]);
}
return 0;
}