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