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 longview codeusing
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
<
}
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 ...