ACM-ICPC 2018 徐州赛区网络预赛 C - dfs计算期望最大值

题目链接:点击这里

 

解题思路:

对于这么一个3*3的格子一共就是有八种选择,那么题目要求在这八种的选择的的值的期望中输出最大的那个.

那么我们首先就去固定'*'号我们不知道而M知道的点,将他变为已知的值,然后再去暴力dfs枚举'#'号的值,求出这次所有‘*’号固定的情况的八种中的最大期望.最后将最大期望和对固定'*'号方案数求均值就是最后最大值期望了.

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mx = 3e5 + 10;
int n,m,top,siz[10];
int a[25],num1,num2;
double ans1,ans2,ans;
bool vis[20];
int b[8][6] = { 0,0,0,1,0,2,
				1,0,1,1,1,2,
				2,0,2,1,2,2,
				0,0,1,0,2,0,
				0,1,1,1,2,1,
				0,2,1,2,2,2,
				0,0,1,1,2,2,
				0,2,1,1,2,0};
void init(){
	memset(a, 0, sizeof(a));
	a[6] = 10000;
	a[7] = 36;
	a[8] = 720;
	a[9] = 360;
	a[10] = 80;
	a[11] = 252;
	a[12] = 108;
	a[13] = 72;
	a[14] = 54;
	a[15] = 180;
	a[16] = 72;
	a[17] = 180;
	a[18] = 119;
	a[19] = 36;
	a[20] = 360;
	a[21] = 1080;
	a[22] = 144;
	a[23] = 1800;
	a[24] = 3600;
}
char str[10][10];
void dfs2(int *p,int x,int c)
{
	if(c==3){
		num2++;
		ans2 += a[str[p[0]][p[1]]+str[p[2]][p[3]]+str[p[4]][p[5]]-3*'0'];
		return ;
	}
	if(str[p[x]][p[x+1]]=='#')
	for(int i=1;i<=9;i++){
		if(!vis[i]){
			vis[i] = 1;
			str[p[x]][p[x+1]] = i + '0';
			dfs2(p,x+2,c+1);
			vis[i] = 0;
			str[p[x]][p[x+1]] = '#';			
		}
	}
	else dfs2(p,x+2,c+1);
}
void dfs1(int x,int y,int c)
{
	if(!c){
		num1++,ans1 = 0;
		for(int i=0;i<8;i++){
			ans2 = num2 = 0;
			dfs2(b[i],0,0);
			ans1 = max(ans1,ans2/num2);
		}
		ans += ans1;
		return ;
	}
	if(str[x][y]=='*')
	for(int k=1;k<=9;k++){
		if(!vis[k]){
			str[x][y] = k + '0';
			vis[k] = 1;
			dfs1(y==2?x+1:x,y==2?0:y+1,c-1);
			vis[k] = 0;
			str[x][y] = '*';
		}
	}
	else dfs1(y==2?x+1:x,y==2?0:y+1,c);
}
int main()
{
	init();
	scanf("%d",&n);
	while(n--)
	{
		memset(vis,0,sizeof(vis));
		for(int i=0;i<3;i++) scanf("%s",str[i]);
		int cnt = 0;
		num1 = num2 = 0;
		ans = ans1 = ans2 = 0;
		for(int i=0;i<3;i++){
			for(int j=0;j<3;j++){
				if(str[i][j]=='*') cnt++;
				else vis[str[i][j]-'0'] = 1;
			}
		}
		dfs1(0,0,cnt);
		//cout << ans << " " << num1 << endl; 
		printf("%.8lf\n",1.0*ans/num1);
	}
	return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值