bzoj4565 HAOI2016 字元合併

2022-03-25 05:27:24 字數 1192 閱讀 6876

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

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

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

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

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

輸出乙個整數表示答案

3 2101

1 10

1 10

0 20

1 3040

//第3行到第6行表示長度為2的4種01串合併方案。00->1,得10分,01->1得10分,10->0得20分,11->1得30分。

dpf[i][j][0]和f[i][j][1]表示區間[i,j]合併為0或1的最大分數。

g[j][k]表示當前的i到j合併為k的最大分數。

然後是很麻煩的轉移,詳見程式。

#include

#include

#include

#include

#include

#include

#define f(i,j,n) for(int i=j;i<=n;i++)

#define d(i,j,n) for(int i=j;i>=n;i--)

#define ll long long

#define n 300

using namespace std;

int n,m;

ll w[n],c[n],f[n][n][2],g[n][n],tmp[2],ans[n];

char s[n];

inline int read()

while (ch>='0'&&ch<='9')

return x*f;

}int main()

now++;

if (now==m)

}} f(i,1,n) for(int j=i;j<=n;j+=m-1) ans[j]=max(ans[j],ans[i-1]+max(f[i][j][0],f[i][j][1]));

printf("%lld\n",ans[n]);

}

4565 Haoi2016 字元合併

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

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 ...

BZOJ1055 HAOI 玩具取名

某人有一套玩具,並想法給玩具命名。首先他選擇wing四個字母中的任意乙個字母作為玩具的基本名字。然後 他會根據自己的喜好,將名字中任意乙個字母用 wing 中任意兩個字母代替,使得自己的名字能夠擴充得很長。現在,他想請你猜猜某乙個很長的名字,最初可能是由哪幾個字母變形過來的。第一行四個整數w i n...