阅读量: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(); } }