[問題]zerojudge競賽題目b841:104北二5.骨牌遊戲

作者: vagrantlike (【傑克】喵嗚)   2016-07-17 19:38:37
http://zerojudge.tw/ShowProblem?problemid=b841
對於遞迴題目真的是苦手 T.T
想要做的是迭代長方形每個格子點
從上下右左的順序依次檢查是否可連成骨牌
並遞迴產生所有的狀態
再從中選擇骨牌數最多者
遇到的問題是
1>某點有相鄰相同數字可連成骨牌時如何不選擇該點
保留給後面其他點有選擇機會因也許能產生更多骨牌
2>遞迴終止條件設定也有問題...
3>目前寫法仔細想想根本不是遞迴
能否提供建議或想法?謝謝
///////////////////////
以下是我的程式碼
//////////////////////
#include <stdio.h>
#include <stdlib.h>
int H = 0,W = 0;
int board[6][6] = {0};
#include <stdio.h>
#include <stdlib.h>
int H = 0,W = 0;
int board[6][6] = {0};
//-2:初始值;0:先前曾有機會選擇但放棄未選;-1:已被其他相鄰格子選擇過;
int flag[6][6] = {-2};
int maxN = -987654321,cnt = 0;
int main() {
int i=0,j = 0;
while(scanf("%d %d",&H,&W)==2) {
memset(flag,-2,sizeof(flag));
for(i=0; i<H; ++i) {
for(j=0; j<W; ++j) {
scanf("%d",&board[i][j]);
}
}
for(i=0; i<H; ++i) {
for(j=0; j<W; ++j) {
if(flag[i][j]!=-1) {
dfs(i,j,&cnt);
}
}
}
printf("%d\n",cnt);
}
return 0;
}
int dfs(int x, int y,int *id) {
int i =0,j = 0;
// 終止條件
if(x==H-1 && y==W-1) {
if(*id>maxN)
maxN = *id;
return;
} else {
if(flag[x][y]!=-1) {
//上,右,下,左
//?不選?
if(board[x-1][y]==board[x][y] && flag[x-1][y]!=-1) {
//選擇他
flag[x][y] = flag[x-1][y] = -1;
++*id;
dfs(x-1,y,*id);
//不選擇他
//flag[x][y] = flag[x-1][y] = 0;
//dfs(x-1,y,
作者: FRAXIS (喔喔)   2016-07-18 08:33:00
你給的題目連結不能點..
作者: yvb   2016-07-19 14:11:00
網址最後的 problemid=b8 應改為 problemid=b841
作者: vagrantlike (【傑克】喵嗚)   2016-07-19 22:52:00
感謝 連結已修正‘
作者: chchwy (mat)   2016-07-20 08:53:00
考慮用 https://paste.plurk.com/ 來貼長段code吧
作者: yr (Sooner Born Sooner Bred)   2016-07-20 21:55:00
先把數字區塊找出來再去遞迴找出該區塊可以有幾組如何?size = 2,3 就不用算了
作者: vagrantlike (【傑克】喵嗚)   2016-07-21 21:39:00
to yr:有思考過你提的這種方式 就是典型DFS找範圍內有幾塊油田題目的變形 只是這時同一塊油田有相同數字 應該是可行的to chchwy:這段程式碼其實尚未完成 只是想用來記錄目前想到的解法 他是無法執行的。。。
作者: yr (Sooner Born Sooner Bred)   2016-07-21 22:42:00
不知道我是不是想得太複雜,區塊可以轉成 graph然後相當於要找該 graph 的 maximum matchingO(V^2 * E)
作者: vagrantlike (【傑克】喵嗚)   2016-07-21 23:23:00
剛搜尋graph 的 maximum matching 似乎是可行的但有殺雞焉用牛刀的感覺 直覺有更簡單的思路可解...http://www.csie.ntnu.edu.tw/~u91029/Matching.html
作者: FRAXIS (喔喔)   2016-07-22 08:36:00
這個圖是 bipartite 的 所以應該很容易算maximum matching
作者: yr (Sooner Born Sooner Bred)   2016-07-22 10:06:00
嗯嗯,沒發現是 bipartite ,這樣就好解很多研究了一下,跑個 bfs 算奇數層跟偶數層的點數量,取小的這算法不知道有沒忽略特殊情況?實作 http://pastebin.com/75a9Tm3n 只測過網頁那個
作者: FRAXIS (喔喔)   2016-07-22 22:22:00
bipartite maximum matching 應該是用 network flow 吧...
作者: yr (Sooner Born Sooner Bred)   2016-07-22 22:46:00
因為只要算數量, bipartite maximum matching 相當於minimum size of a vertex cover ,因為 graph 特性關係,似乎可以直接用 bfs 去求graph 特性是指本題產生的 graph查了一下,一般是解西洋棋棋盤拿掉部分,連著的區塊可以完全覆蓋要偶數格跟黑白格數一樣多
作者: FRAXIS (喔喔)   2016-07-23 11:24:00
但是這題有要完全覆蓋嗎?
作者: yr (Sooner Born Sooner Bred)   2016-07-23 11:44:00
我的想法是,可以覆蓋的組數跟顏色少的格子一樣多,不知道這想法正不正確似乎可以用 Hall's theorem 來證明
作者: FRAXIS (喔喔)   2016-07-23 12:13:00
你有沒有試著找找反例?
作者: yllan (藍永倫)   2016-07-24 13:10:00
這題最大只有6x6,原po可能想問最基本的暴力法吧~

Links booklink

Contact Us: admin [ a t ] ucptt.com