$\huge \color{orange}{成魔之路->}$ $\huge \color{purple}{算法提高课题解}$
思路:
1. f[a][b][c][d][x][y]表示选黑桃a张,红桃b张,梅花c张,方块d张,大王(x!=4)张,小王(y!=4)张的期望值
2. 选黑桃:f[a][b][c][d][x][y] += f[a+1][b][c][d][x][y]
3. 选红桃:f[a][b][c][d][x][y] += f[a][b+1][c][d][x][y]
4. 选梅花:f[a][b][c][d][x][y] += f[a][b][c+1][d][x][y]
5. 选方块:f[a][b][c][d][x][y] += f[a][b][c][d+1][x][y]
6. 选大王:f[a][b][c][d][x][y] = min{f[a][b][c][d][x'][y]} (0 <= x' <= 3)
7. 选小王:f[a][b][c][d][x][y] = min{f[a][b][c][d][x][y']} (0 <= y' <= 3)
完整代码
#include<bits/stdc++.h>
using namespace std;
const int N = 15;
const double INF = 1e20;
int A,B,C,D;
double f[N][N][N][N][5][5];
double dp(int a,int b,int c,int d,int x,int y)
{
// a表示黑桃的数量,b表示红桃的数量,c表示梅花的数量,d表示方块的数量
double &v=f[a][b][c][d][x][y]; //(x != 4)表示大王的数量,(y != 4)表示小王的数量
if(v>=0) return v;
int as=a+(x==0)+(y==0); //黑桃数量
int bs=b+(x==1)+(y==1); //红桃数量
int cs=c+(x==2)+(y==2); //梅花数量
int ds=d+(x==3)+(y==3); //方块数量
if(as>=A&&bs>=B&&cs>=C&&ds>=D) return v=0;
int sum=as+bs+cs+ds; //已选牌总数
sum=54-sum;
if(sum<=0) return INF;
v=1;
if(a<13) v+=(13.0-a)/sum*dp(a+1,b,c,d,x,y); //选黑桃
if(b<13) v+=(13.0-b)/sum*dp(a,b+1,c,d,x,y); //选红桃
if(c<13) v+=(13.0-c)/sum*dp(a,b,c+1,d,x,y); //选梅花
if(d<13) v+=(13.0-d)/sum*dp(a,b,c,d+1,x,y); //选方块
if(x==4) //选大王
{
double t=INF;
for(int i=0;i<4;i++) t=min(t,1.0/sum*dp(a,b,c,d,i,y)); //选期望最小值
v+=t;
}
if(y==4) //选小王
{
double t=INF;
for(int i=0;i<4;i++) t=min(t,1.0/sum*dp(a,b,c,d,x,i)); //选期望最小值
v+=t;
}
return v;
}
int main()
{
scanf("%d%d%d%d",&A,&B,&C,&D);
memset(f,-1,sizeof f);
double t=dp(0,0,0,0,4,4);
if(t>INF/2) t=-1;
printf("%.3lf\n",t);
return 0;
}
6维数组恐怖如斯
这道题还是很简单的
大佬不知小弟菜,我leetCode中等题都是看命AC