UVA10559&P2135 方塊消除 題解
阿新 • • 發佈:2021-06-16
消除方塊 傳送門
看了看題解區好像沒有這樣的解法?
這是一種比較懶癌的解法。(也比較詳細
首先來說說看狀態, \(f_{i,j,k}\)表示\([i, j]\)範圍消除完之後,剩餘k個顏色為\(color_{i}\)的最大分數
比如\(f_{i,j,0}\)表示把\([i, j]\)完全消除(啥都不剩)的最大分數
那麼問題來了我們為什麼要怎麼設呢?
想想看對於每一個塊我們只有兩種操作,
一種單獨消掉
一種是和其他塊組合起來消掉:比如12221, 我們可以把222消掉,然後讓11組合起來
對,也就是說,當我們要把兩個塊組合起來時, 一定要把他們之間的所有塊先消除, 例如把i, k組合起來,要先把\([i+1, k-1]\)
當我們計算\(f_{i, j, k}\)時, 假設i是新放進去的塊([i+1, j]已經計算好了)
直接消掉i顯然為\(1+f_{i+1, j, 0}\), 進一步考慮組合
我們列舉\([i+1, j]中每一個為color_{i}的塊k\)
我們考慮在\([k, j]\)中選擇若干個塊與i合併 分數為\(f_{k,j,x}\)(剩餘x個用來合併) \([i+1, k-1]\)直接消掉\(f_{i+1, k-1, 0}\)
列舉這個x,ok
(這個地方需要仔細思考)
複雜度\(O(n^4)\)
實在不行看看程式碼
for(int i=1; i<=n; i++){ f[i][i][1] = 0;//直接把這個塊保留,不需要消除,所以分數為0 f[i][i][0] = 1;//直接消除這一個塊, 分數1 } for(int j=2; j<=n; j++){ for(int i=1; i+j-1<=n; i++){ int l=i, r=i+j-1; f[l][r][0] = f[l+1][r][0] + 1;//直接消除i f[l][r][1] = f[l+1][r][0];//直接保留i for(int st=l+1; st<=r; st++){ if(color[st] != color[l]) continue;//列舉上面的“x” for(int k=1; k<n; k++){//注意邊界 f[l][r][k+1] = max(f[l][r][k+1], f[l+1][st-1][0] + f[st][r][k]); //從st-r中取k個與i合併, 一共k+1個 f[l][r][0] = max(f[l][r][0], f[l][r][k+1] + (k+1)*(k+1)); //考慮把k+1個直接消除, 更新最大分數 } } } }