日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

源哥每日一题第十七弹 poj 1568 Alpha-Beta剪枝

發(fā)布時間:2025/7/14 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 源哥每日一题第十七弹 poj 1568 Alpha-Beta剪枝 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鏈接:http://poj.org/problem?id=1568

題目:為什么是英文啊題目就是給你一個4*4的OX棋盤,上面已經下了一些棋,然后現在輪到X下,問你有沒有一個必勝的方法,有的話就輸出坐標,沒有輸出#####

北大的又一神題。一個很簡單的思路很容易就能想到,遍歷所有可能的下法,暴力搜看有沒有一種情況,無論O怎么下,X都能贏。但是這樣復雜度太高了。

然后一個非常神奇的關于棋盤類的博弈搜索方法就出來了:

先說說極大極小搜索法:和正常搜索不同的是,這種搜索限制了搜索深度。當然,搜索到了限定深度之后,非常有可能找不到結果。怎么辦呢?給出一個當前狀態(tài)的得分(估價函數)作為評價當前狀態(tài)優(yōu)劣的指標。放到本題,就是對于X越有利的狀態(tài),得分越高;對X越不利的狀態(tài),得分越低。一個比較成熟的思路就出現了:到X下的時候,找所有兒子里得分最高的;到O下的時候,找所有兒子里得分最低的。

差不多就是這個樣子(圖片來自北大課件):

?Alpha–beta給出了準確的剪枝方法。

這個剪枝分為兩部分:

alpha剪枝:如圖:當搜到X的時候,由于R=K>X,所以R的值不會因為X子節(jié)點值的改變而改變,所以,可以剪掉X除Y之外的枝。即:當前為極小值X節(jié)點,其兄弟節(jié)點中,已經找到了最大值a那么在搜索X的時候,如果某個子節(jié)點Y<=a,則不用考慮后面的節(jié)點了。(極大值剪枝)

?

beta剪枝:當前為極大值X節(jié)點,其兄弟節(jié)點中,已經找到了最小值b那么在搜索X的時候,如果某個子節(jié)點Y>=b,則不用考慮后面的節(jié)點了。(極小值剪枝)

回到這個題。這個題估價函數只有三種情況,既1(勝),0(平),-1(負)也就是說,只要找到一個估價為1的方法就可以。

p.s. 出現了一個神級優(yōu)化:chess<=4

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; string mp[5]; int X,Y,chess; int Mindfs(int x,int y, int alpha); int Maxdfs(int x,int y, int beta); int jud(char a) {if(a=='o') return 1;else if(a=='x') return -1;else return 0; } int chk(int x,int y) {int ans = 0;for (int i = 0; i < 4; i++) ans+=jud(mp[x][i]);if(abs(ans)==4) return 1;ans = 0;for (int i = 0; i < 4; i++)ans+=jud(mp[i][y]);if(abs(ans)==4) return 1;ans = 0;for (int i = 0; i < 4; i++)ans+=jud(mp[i][i]);if(abs(ans)==4) return 1;ans = 0;for (int i = 0; i < 4; i++)ans+=jud(mp[i][3-i]);if(abs(ans)==4) return 1;return 0; }int Mindfs(int x,int y,int alpha) {int ans = 1;if (chk(x,y)) return 1;if (chess == 16) return 0;for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {if(mp[i][j] == '.') {mp[i][j] = 'o'; chess++;int t = Maxdfs(i,j,ans);mp[i][j] = '.';chess--;ans = min(ans,t);if(ans <= alpha) {return ans;}}}}return ans; }int Maxdfs(int x,int y,int beta) {int ans = -1;if (chk(x,y)) return -1;if (chess == 16) return 0;for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {if(mp[i][j] == '.') {mp[i][j] = 'x';chess++;int t = Mindfs(i,j,ans);mp[i][j] = '.';chess--;ans = max(ans,t);if(ans >= beta) {return ans;}}}}return ans; }int sol() {int alpha = -1;for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {if(mp[i][j] == '.') {mp[i][j] = 'x';chess++;int t = Mindfs(i,j,alpha);mp[i][j] = '.';chess--;if(t == 1) {X = i; Y = j;return 1;}}}}return 0; } int main() { #ifndef ONLINE_JUDGEfreopen("D:\\fengyu\\Jiang_C\\.vscode\\in.txt","r",stdin);freopen("D:\\fengyu\\Jiang_C\\.vscode\\out.txt","w",stdout); #endifstring s;while(cin >> s && s[0] != '$') {chess = 0;for (int i = 0; i < 4; i++) {cin >> mp[i];for (int j = 0; j < 4; j++) {chess += mp[i][j] != '.';}}if(chess <= 4 || !sol()) {puts("#####");} else {printf("(%d,%d)\n",X,Y);}}return 0; }

  

轉載于:https://www.cnblogs.com/fengyuzhicheng/p/9180918.html

總結

以上是生活随笔為你收集整理的源哥每日一题第十七弹 poj 1568 Alpha-Beta剪枝的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。