「BZOJ3791」作业

时间:2023-03-09 02:54:24
「BZOJ3791」作业

题解:

比正解的做法要复杂

正解直接确定了最多有2k-1段

并且可以证明2k-1是一定可以覆盖的

于是可以直接dp

我的想法是先覆盖一段黑的,然后白的覆盖上去

所以f[i][0/1/2][0/1/2]

表示当前下面那层颜色是啥,上面那层颜色是啥

代码:

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
const int N=1e5+;
int n,kk,a[N];
int f[N][][][];
const int INF=1e9;
IL int max(rint x,rint y)
{
return x>y?x:y;
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n>>kk;
rep(i,,n) cin>>a[i];
rep(k,,)
{
rep(i,,)
rep(j,,)
f[][k][i][j]=-INF;
f[][k][][]=;
}
rep(i,,n)
rep(k,,kk)
{
int (*f1) []=f[i][k],(*f2) []=f[i-][k],(*f4) [];
if (k) f4=f[i][k-];
int ans1=,ans2=,ans3=,ans4=,ans5=;
rep(k1,,)
rep(k2,,)
ans1=max(ans1,f2[k1][k2]);
f1[][]=ans1;
ans2=max(f2[][],f2[][]);
if (k) ans2=max(ans2,f4[][]);
if (a[i]==) ans2++;
f1[][]=ans2;
ans3=max(f2[][],f2[][]);
if (k) ans3=max(ans3,f4[][]);
if (a[i]==) ans3++;
f1[][]=ans3;
ans4=f2[][];
if (k) ans4=max(ans4,f4[][]);
if (a[i]==) ans4++;
f1[][]=ans4;
ans5=f2[][];
if (k) ans5=max(ans5,f4[][]);
if (a[i]==) ans5++;
f1[][]=ans5;
}
int ans=;
rep(i,,)
rep(j,,)
ans=max(ans,f[n][kk][i][j]);
cout<<ans<<endl;
return ;
}