您的位置:首页 > 其它

UvaLive 5811 概率DP

2017-03-17 15:38 405 查看
题意 : 有54张牌 问抽多少张牌能使每种花色都至少是给定的数字 两张王牌可以被选择为任何花色

高放学长真是太腻害辣!

设置dp[][][][][x][y] 前四维代表四种真的花色的数量 后两维xy代表大王与小王的使用情况——是没有用到 还是作为1234

于是dp[i][j][k][l][x][y]当x为0时 可以来自于dp[i][j][k][l][1][y] dp....[2][y]....

期望倒推 所以 当前的四种状态都已经算出来了 选一个最小的 即“选一个最小的期望转变” // 事实上我们已经知道四种分支各自还需要抽牌的期望了

当ijkl<13时 还可能来自于dp[i+1][k][j][l][x][y] 即正常抽牌

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<map>
#include<iostream>
#include<string>
#include<vector>
#include<queue>
using namespace std;
#define L long long

double dp[16][16][16][16][5][5] ;
bool f[16][16][16][16][5][5] ;
int a,b,c,d;

int main(){
int t;
scanf("%d",&t);
int cas = 1 ;
while(t--) {
scanf("%d%d%d%d",&a,&b,&c,&d) ;
int jz=0;
if(a>13)jz+=(a-13);
if(b>13)jz+=(b-13);
if(c>13)jz+=(c-13);
if(d>13)jz+=(d-13);
if(jz>2){
printf("Case %d: -1.000\n",cas++);
continue;
}
memset(dp,0,sizeof(dp));
memset(f,false,sizeof(f));
for(int i=13;i>=0;i--){
for(int j=13;j>=0;j--){
for(int k=13;k>=0;k--){
for(int l=13;l>=0;l--){
for(int x=4;x>=0;x--){
for(int y=4;y>=0;y--){
int aa=i,bb=j,cc=k,dd=l;
if(x==1)aa++;
else if(x==2)bb++;
else if(x==3)cc++;
else if(x==4)dd++;
if(y==1)aa++;
else if(y==2)bb++;
else if(y==3)cc++;
else if(y==4)dd++;
if(aa>=a&&bb>=b&&cc>=c&&dd>=d){

}
else {
f[i][j][k][l][x][y] = true ;
}
}
}
}
}
}
}
for(int i=13;i>=0;i--){
for(int j=13;j>=0;j--){
for(int k=13;k>=0;k--){
for(int l=13;l>=0;l--){
for(int x=4;x>=0;x--){
for(int y=4;y>=0;y--){
int aa=i,bb=j,cc=k,dd=l;
if(x==1)aa++;
else if(x==2)bb++;
else if(x==3)cc++;
else if(x==4)dd++;
if(y==1)aa++;
else if(y==2)bb++;
else if(y==3)cc++;
else if(y==4)dd++;
if(f[i][j][k][l][x][y]==true){
f[i][j][k][l][x][y]=false;
int sum=54-aa-bb-cc-dd;
int s=0;
if(x!=0)s++;
if(y!=0)s++;
dp[i][j][k][l][x][y] = 1.0 ;
if(x==0){
double u = min(min(dp[i][j][k][l][1][y],dp[i][j][k][l][2][y]),min(dp[i][j][k][l][3][y],dp[i][j][k][l][4][y])) ;
dp[i][j][k][l][x][y] += u * 1.0/sum ;
}
if(y==0){
double u = min(min(dp[i][j][k][l][x][1],dp[i][j][k][l][x][2]),min(dp[i][j][k][l][x][3],dp[i][j][k][l][x][4])) ;
dp[i][j][k][l][x][y] += u * 1.0/sum ;
}
if(i<13)dp[i][j][k][l][x][y] += dp[i+1][j][k][l][x][y] * (13-i)*1.0/sum ;
if(j<13)dp[i][j][k][l][x][y] += dp[i][j+1][k][l][x][y] * (13-j)*1.0/sum ;
if(k<13)dp[i][j][k][l][x][y] += dp[i][j][k+1][l][x][y] * (13-k)*1.0/sum ;
if(l<13)dp[i][j][k][l][x][y] += dp[i][j][k][l+1][x][y] * (13-l)*1.0/sum ;
}
}
}
}
}
}
}
printf("Case %d: %.3f\n",cas++,dp[0][0][0][0][0][0]);
}
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: