1767 字元合併

2022-05-25 04:03:13 字數 1263 閱讀 1167

description

有乙個長度為 n 的 01 串,你可以每次將相鄰的 k 個字元合併,得到乙個新的字元並獲得一定分數。得到的新字

符和分數由這 k 個字元確定。你需要求出你能獲得的最大分數。

input

第一行兩個整數n,k。接下來一行長度為n的01串,表示初始串。接下來2k行,每行乙個字元ci和乙個整數wi,ci

表示長度為k的01串連成二進位制後按從小到大順序得到的第i種合併方案得到的新字元,wi表示對應的第i種方案對應

獲得的分數。1<=n<=300,0<=ci<=1,wi>=1,k<=8

output

輸出乙個整數表示答案

sample input

3 2101

1 10

1 10

0 20

1 30

sample output

40【題解】

發現k很小,可以考慮狀壓。

定義f[i][j][s]表示原串第i到j個字元合成成狀態s所獲得最大的分數。

初值:f[i][i][kai[i]]=0;其他=-inf。

轉移:考慮到一段數肯定合得越多越優,所以一段中肯定合得不能再合,剩下的數的個數就是hu=(len-1)%(k-1)。

所以列舉這一段的狀態為0---(1<

考慮到一段數肯定是從左邊乙個區間乙個s1和右邊乙個區間s2合併而得,所以可以令右邊的區間只剩下乙個數,又是乙個舒服的優化。

如果hu==0即剩下了k個數,則可以列舉每乙個狀態,f[i][j][c[s]]=f[i][j][s]+w[s]。

**如下:

#include#define int long long

using

namespace

std;

const

int n=305

;int

n,k,kai[n],c[n],w[n],f[n][n][n];

inline

intread()

while(isdigit(c))

return x*f;

}signed main()

for(int i=2;i<=n;i++)

if(she==k-1

) }}

int ans=-0x3f3f3f3f

;

for(int i=0;i<1

<1

][n][i]);

cout

<

}

view code

4565 Haoi2016 字元合併

time limit 20 sec memory limit 256 mb submit 154 solved 70 submit status discuss 有乙個長度為 n 的 01 串,你可以每次將相鄰的 k 個字元合併,得到乙個新的字元並獲得一定分數。得到的新字 符和分數由這 k 個字元確...

bzoj4565 HAOI2016 字元合併

time limit 20 secmemory limit 256 mb有乙個長度為 n 的 01 串,你可以每次將相鄰的 k 個字元合併,得到乙個新的字元並獲得一定分數。得到的新字 符和分數由這 k 個字元確定。你需要求出你能獲得的最大分數。第一行兩個整數n,k。接下來一行長度為n的01串,表示初...

4565 Haoi2016 字元合併 區間DP

令fi j,k 表示區間 i j 合併成 k 的最大收益,其中k 0 1保證 i,j 可以合併成乙個數。轉移的時候用gj k表示對於當前的 i i j 合併成了 k 其中 k是乙個二進位制數。然後轉移一下就行了 include include include using namespace std ...