BZOJ2121 字串遊戲

2022-05-31 05:54:11 字數 1058 閱讀 9697

題解:

有難度的dp

感覺比較容易想到的dp是f[i][j]表示能否完全刪除

轉移時列舉i',j'轉移,這樣用hash可以做到l^4

但是 這是錯的

因為我們可以將序列分為三段或者更多段相加

所以剛才的定義是有問題的

既然可以多段我們顯然不能暴力列舉,那麼我們就記錄匹配了多少

f[i][j][k][l]表示i-j這段區間,能否匹配到k的l處

然後問題在於轉移

第一種直接多匹配一位是很簡單的

第二種在於要匹配一堆字元

我們能否直接列舉乙個串來解決的

很明顯示不能的,因為同剛才說的可能是多個搞在了一起形成的

所以我們還需要乙個狀態p[i][j]表示i-j能否被完全刪除

時間複雜度l^3*n*m

資料不是很強加上有很多冗餘狀態於是就過了

網上**有一些卡常數的東西。。

1.區間dp壓掉一維,將區間dp變為從右向左列舉左端點,從左向右列舉右端點

2.最後一維狀壓,注意轉移那裡如果狀壓是可以做到(n+m)的

複雜度l^3*(n+m)

#include using

namespace

std;

#define rint register int

#define il inline

#define rep(i,h,t) for (rint i=h;i<=t;i++)

#define dep(i,t,h) for (rint i=t;i>=h;i--)

char c[200],s[200][200

];int

m;bool f[152][152][31][21],g[152][152

];int t[152

];int

main()

}rep(i,

1,n)

t[i]=max(t[i-1

],t[i]);

} cout

return0;

}

bzoj 2121 字串遊戲

題目大意 給你乙個大字串和乙個字串的集合,每次可以從字串的集合中選出乙個,如果那個大字串中包含了這個字串,就可以從大串中將小串刪掉,刪完後兩邊接起來,求刪完後大串最少剩幾個字元 大串 150,小串 20,小串個數 30 這題沒想著怎麼做,主要還是太弱了。首先可以設f i j k l 代表第i個到第j...

bzoj 2121 字串遊戲

bx正在進行乙個字串遊戲,他手上有乙個字串l,以及其他一些字串的集合s,然後他可以進行以下操作 對於乙個在集合s中的字串p,如果p在l中出現,bx就可以選擇是否將其刪除,如果刪除,則將刪除後l 成的左右兩部分合併。舉個例子,l abcdefg s 如果bx選擇將 de 從l中刪去,則刪後的l abc...

BZOJ2121 字串遊戲

區間dp 用c l r 表示l r是否能被全部刪掉,f l r k x 表示l r和第k個串匹配是否能匹配到第x位,注意到小串的長度 21,而且f是個bool變數,所以可以把x壓成int,而推一下f的轉移方程發現對於不同的l,他們之間是互不影響的,所以可以把l這一維刪掉 那麼列舉左端點,f r k ...