剛開始想了一種奇怪的方法去貪心,因為不是正確的就不貼了,然後t了……
題解寫的是ida*,其實是迭代加深和剪枝。
剪枝的地方有幾處:
1.估價函式剪枝,還剩幾種顏色估計幾步
2.無效剪枝,如果當前這個顏色已經沒有就不用走這一步了
整體的思路是這樣的
把原圖按照顏色做乙個連通塊,然後原圖可以分為三個部分:和(1,1)連通的點、和(1,1)連通的點相鄰的點、其他點
那麼,每次只在這些和(1,1)連通點相鄰的點上選取顏色,然後就是乙個接近暴力的過程。
因為陣列稍多,重複訪問不可承受。所以採取每次列舉當前變換成的顏色,然後標記掉相鄰的相同顏色的點。
每個點用它的連通塊標號來判斷是否已經訪問過,避免訪問整個8*8陣列的情況。
失分點:
1. 根據資料範圍應該猜測為搜尋,然而一開始思路就錯了。
2. 剪枝沒有充分,特別是無效剪枝一塊,不加就t了
學習處:
1. 搜尋剪枝的範圍會很小,大概猜測10以內為1s,20以內為2-3s
2. 剪枝分為:最優性剪枝、無效剪枝、估價函式剪枝等
#include
using
namespace
std;
typedef pair pii;
const
int maxn = 8 + 1;
int g[maxn][maxn], n;
bool vis[maxn][maxn], use[maxn * maxn];
int bccno[maxn][maxn], bcccnt, col[maxn * maxn];
int ans;
int dx = ;
int dy = ;
bool validpos(int x, int y)
int predit()
int getcnt(int c)
}if(ok) res++;}}
}return res;
}bool dfs(int dep)
else
if(dep + pre > ans) return
false;
// printf("dep = %d, use = ");
// for(int i = 1 ; i <= bcccnt ; i++) printf("%d ", use[i]);
// puts("");
bool tuse[maxn * maxn];
memcpy(tuse, use, sizeof use);
for(int c = 0 ; c < 6 ; c++)
}use[bccno[i][j]] = ok;}}
}// system("pause");
if(dfs(dep + 1)) return
true;
memcpy(use, tuse, sizeof tuse);
}return
false;
}void dfsbcc(int x, int y, int mark)
}}int main()}}
for(int i = 1 ; i <= bcccnt ; i++) use[i] = false;
use[1] = true;
ans = 0;
while(dfs(0) == false) ans++;
printf("%d\n", ans);
}return
0;}
11年福州 F 次小生成樹變形 樹形DP
單獨練習的時候,做到最小生成樹處理出來後,就不知道怎麼處理了。關鍵是兩個子樹間的距離,不能在有效的時間複雜度內解決。實際上,對於乙個最小生成樹,兩個子樹間距離可以用dp來做。假設從root開始向下搜尋,那麼dp root u 表示root到u和以u為根節點的子樹的最小距離,此處距離即是取的不在最小生...
2023年2月15日到福州
1.廣西datastage安裝,由於伺服器中 etc host檔案,主機名和ip位址對應錯誤問題,導致datastage無法編譯,報錯提示連線不到10000埠 安裝oracle的時候,改的host檔案,導致錯誤,當心!2.重慶資料庫ora 600的錯誤,未解決 3.重慶sysaus表空間佔滿,同時系...
如何解除安裝oracle11g,10g
1 關閉oracle所有的服務。可以在windows的服務管理器中關閉 2 開啟登錄檔 regedit 開啟路徑 hkey local machine system currentcontrolset services 刪除該路徑下的所有以oracle開始的服務名稱,這個鍵是標識oracle在win...