2024牛客多校之MinMax解法

avatar
作者
筋斗云
阅读量:0

最清晰易懂的MinMax算法和Alpha-Beta剪枝详解-CSDN博客

MinMax的算法流程就是

(1)首先构建整个博弈树

(2)题设肯定就是一个人和另外一个人进行交替选择进行的步骤。那么每一层对应一个min和max。min就是最小化对手的选择,max就是最大化自己的选择。

(3)整个算法流程是先从上到下遍历到每一个叶子节点,算出每一个叶子节点的估计价值。然后从下网上进行一层层的minmax取值。直到最后的根层。

(4)最后从下面的传递上来的估计函数价值就是最后的结果。如果想要找到路径,那么就是从根节点 对应每一层选取minmax的数值。然后就可以选出这一条路径。

例题:

A-Cake_2024牛客暑期多校训练营6 (nowcoder.com)

#include<bits/stdc++.h> using namespace std; #define int long long const int N=1e6+100; vector<double>dp(N); vector<double>ans(N); vector<int>sum0(N),d(N); vector<pair<int,int>>e[N]; void dfs(int u,int fa,int dep){ 	double minn=2,maxx=-1; 	for(auto [v,w]:e[u]){ 		if(fa==v) continue; 		sum0[v]=sum0[u]; 		if(w==0) sum0[v]++; 		dp[v]=(double)sum0[v]/(double)(dep+1); 		dp[v]=max(dp[v],dp[u]); //因为随时可以选择最大的0占比所以可以这样 		dfs(v,u,dep+1); 		minn=fmin(minn,ans[v]); 		maxx=fmax(maxx,ans[v]); 	} 	 	if(minn==2&&maxx==-1){ 		ans[u]=dp[u]; 		return; 	} 	if(dep&1) ans[u]=maxx; 	else ans[u]=minn; } void solve(){ 	int n;cin>>n; 	for(int i=1;i<=n;i++){ 	    sum0[i]=0; 		e[i].clear(); 	} 	for(int i=1;i<n;i++) 	{ 		int x,y,w;cin>>x>>y>>w; 		e[x].push_back({y,w}); 		e[y].push_back({x,w}); 	} 	dfs(1,0,0); 	cout<<setprecision(12)<<1-ans[1]<<"\n"; }    signed main(){ 	ios::sync_with_stdio(false); 	cin.tie(0);cout.tie(0); 	int T=1; 	cin>>T; 	while(T--){ 		solve(); 	} }

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!