样例输入1
1 2 3 4
样例输入2
15 15 15 15
样例输出1
16.393
样例输出2
-1.000
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
int A,B,C,D,inf=100000000;
double f[15][15][15][15][5][5];
int read()
{
int ans=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();}
while(isdigit(ch)) {ans=ans*10+ch-‘0‘;ch=getchar();}
return ans*f;
}
bool ok(int a,int b,int c,int d,int w1,int w2)
{
if(w1==1) a++;
if(w1==2) b++;
if(w1==3) c++;
if(w1==4) d++;
if(w2==1) a++;
if(w2==2) b++;
if(w2==3) c++;
if(w2==4) d++;
if(a<A||b<B||c<C||d<D)
return 0;
else return 1;
}
double dp(int a,int b,int c,int d,int w1,int w2)
{
double ans=0,n,mi;
if(f[a][b][c][d][w1][w2]!=-1)
return f[a][b][c][d][w1][w2];
n=a+b+c+d;
if(w1) n++;
if(w2) n++;
if(ok(a,b,c,d,w1,w2))
return 1.0*n;
if(n>=54) return inf; //////////////////////
if(a+1<=13)
ans+=(double)(13-a)*1.0/(54-n)*dp(a+1,b,c,d,w1,w2); //强转
if(b+1<=13)
ans+=(double)(13-b)*1.0/(54-n)*dp(a,b+1,c,d,w1,w2);
if(c+1<=13)
ans+=(double)(13-c)*1.0/(54-n)*dp(a,b,c+1,d,w1,w2);
if(d+1<=13)
ans+=(double)(13-d)*1.0/(54-n)*dp(a,b,c,d+1,w1,w2);
if(!w1)
{
mi=100000000;
for(int i=1;i<=4;i++)
mi=min(mi,dp(a,b,c,d,i,w2));
ans+=mi/(54-n);
}
if(!w2)
{
mi=100000000;
for(int i=1;i<=4;i++)
mi=min(mi,dp(a,b,c,d,w1,i));
ans+=mi/(54-n);
}
return f[a][b][c][d][w1][w2]=ans;
}
int main()
{
int mo=0;
for(int a=0;a<=13;a++)
for(int b=0;b<=13;b++)
for(int c=0;c<=13;c++)
for(int d=0;d<=13;d++)
for(int w1=0;w1<=4;w1++)
for(int w2=0;w2<=4;w2++)
f[a][b][c][d][w1][w2]=-1;
scanf("%d%d%d%d",&A,&B,&C,&D);
if(A>13) mo+=A-13;
if(B>13) mo+=B-13;
if(C>13) mo+=C-13;
if(D>13) mo+=D-13;
if(mo>2)
{
printf("-1.000");
return 0;
}
double res=dp(0,0,0,0,0,0);
printf("%.3lf",res);
return 0;
}
原文:http://www.cnblogs.com/charlotte-o/p/7692552.html