bzoj4565 [Haoi2016] word matches and
Original title address : http://www.lydsy.com/JudgeOnline/problem.php?id=4565
Test Instructions:
There is a 01 string of length n, you can match the adjacent K characters each time and get a new character and get a certain score. The new characters and fractions obtained are determined by this K-character.
You need to ask for the maximum score you can get.
Data Range
1<=n<=300,0<=ci<=1,k<=8, input of 1<=wi<=10^9
The following:
The Dalao of the
N is very small, it is easy to think of n^3 interval dp,k is very small, consider the shape pressure. (then merge, then merge, length <=k)
Dp[i][j][s] Indicates the maximum value of the [i,j] interval being pressed into the S state.
How to solve the 0001,001,01 of the expression confusion.
Think about it and find that when the interval length is certain, the length of the 01 strings It can press is also certain. (Before your own idea is to add another 1 to indicate the length limit)
So we just have to transfer from the legal .
When S is transferred to S<<1, make sure that f[i][j][s<<1] is legal, and that f[m][j][0],0 represents exactly one number.
Therefore, the enumeration m is every k-1 a hop.
([m,j] length k,k+k-1,k+k-1+k-1 ... )
So
F[i][j][s<<1]=max (F[i][j][s<<1],f[i][m-1][s]+f[m][j][0])
F[i][j][s<<1|1]=max (F[i][j][s<<1|1],f[i][m-1][s]+f[m][j][1])
The value is calculated one layer at a time, from a short interval to a long interval of length.
For the case of K merging into one number, the Dp[i][j][s] ((j-i)% (k-1) ==0) plus the corresponding w[s] are transferred.
Note that the 0 length indicated by DP[I][J][0/1] is not 1, so it cannot be updated directly to DP[I][J][0/1], to open a new one to save, and finally to update.
G[c[s]]=max (G[c[s]],f[i][j][s]+w[s]) G[c[s]]=max (G[c[s]],f[i][j][s]+w[s])
F[i][j][0]=g[0] f[i][j][1]=g[1] f[i][j][0]=g[0] \ \ \ f[i][j][1]=g[1]
Code:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define LL Long
Long using namespace std;
const int n=305;
int n,k,w[1<<8],c[1<<8],top,s[n];
LL dp[n][n][1<<8],_inf;
int main () {scanf ("%d%d", &n,&k);
top= (1<<k)-1;
for (int i=1;i<=n;i++) scanf ("%1d", &s[i]);
for (int i=0;i<=top;i++) scanf ("%d%d", &c[i],&w[i]);
Memset (Dp,128,sizeof (DP));//-inf _inf=dp[0][0][0];
for (int i=1;i<=n;i++) dp[i][i][s[i]]=0;
for (int len=2;len<=n;len++) {for (int i=1;i+len-1<=n;i++) {int j=i+len-1; for (int m=j;m>i;m-= (k-1)) {for (int s=0; s<=top; s++) {if (Dp[i][m-1][s]!=_inf) {if (dp[m][
J][0]!=_inf) Dp[i][j][s<<1]=max (dp[i][j][s<<1],dp[i][m-1][s]+dp[m][j][0]); if (dp[m][j][1]!=_iNF) Dp[i][j][s<<1|1]=max (dp[i][j][s<<1|1],dp[i][m-1][s]+dp[m][j][1]);
}}} if (len-1>=k-1&& (len-1)% (k-1) ==0)//Can be shrunk to a {
LL g[2];
G[0]=g[1]=_inf; for (int s=0; s<=top;
s++) if (dp[i][j][s]!=_inf) G[c[s]]=max (G[c[s]],dp[i][j][s]+w[s]); DP[I][J][0]=G[0];
DP[I][J][1]=G[1];
}}} LL ans=0;
for (int i=0;i<=top;i++) Ans=max (Ans,dp[1][n][i]);
printf ("%i64d\n", ans);
return 0; }