首页 > 代码库 > bzoj 3791: 作业

bzoj 3791: 作业

23333开始了为期不知道多少天的DP专题23333

(上来第一个大水题就不会,跪)

k次修改,最多会产生2*k-1个不同的区间。。然后dp搞一下。。(可以压一维)

 1 /*#include<cstdio>
 2 #include<iostream>
 3 #define N 100005
 4 using namespace std;
 5 int n,K,size[N],a[N],f[55][N][2];
 6 int ans,pp,p,qq,q,tot;
 7 int main()
 8 {
 9     scanf("%d %d",&n,&K); a[0]=-1;
10     for (int i=1; i<=n; i++) scanf("%d",&a[i]);
11     for (int i=1; i<=n; i++)
12     {
13         if (a[i]!=a[i-1]) tot++;
14         size[tot]++;
15     }
16     pp=0; qq=1;
17     if (a[1]==1) pp^=1,qq^=1;
18     for (int k=1; k<=K; k++)
19     {
20         p=pp; q=qq;
21         for (int i=1; i<=tot; i++)
22         {
23             f[k][i][p]=max(f[k][i][p],f[k][i-1][p]+size[i]);
24             if (k>1) f[k][i][p]=max(f[k][i][p],size[i-1]+f[k-1][i-2][p]+size[i]);
25             f[k][i][q]=max(f[k][i][q],f[k][i-1][q]);
26         //    ans=max(f[k][i][p],ans);
27         //    if (ans==6) printf("%d %d %d     %d\n",k,i,p,f[k][i][p]);
28             p^=1; q^=1;
29         }
30     }
31     printf("%d",max(f[K][tot][1],f[K][tot][0]));
32     return 0;
33 }*/
34 /*
35 19 2
36 1 1 1 --0 0 0 0 1 0 1 1 1 0 1 0 0 0 0 --1     
37 */
38 
39 #include<cstdio>
40 #include<iostream>
41 #define N 100005
42 using namespace std;
43 int n,K,ans;
44 int a[100005],f[2][105][2];
45 int main()
46 {
47     scanf("%d%d",&n,&K);
48     for (int i=1; i<=n; i++) scanf("%d",&a[i]);
49     f[1][1][a[1]]=1;
50     for (int i=1,p=1,q=0; i<n; i++,swap(p,q))
51     {
52         for (int j=1; j<=2*K-1; j++)
53             for (int x=0; x<2; x++)    
54                 for (int y=0; y<2; y++)
55                     f[q][j+(x!=y)][y]=max(f[q][j+(x!=y)][y],f[p][j][x]+(a[i+1]==y));
56         for (int j=1; j<=2*K-1; j++)
57         {
58             f[p][j][0]=f[p][j][1]=0;
59             ans=max(ans,max(f[q][j][1],f[q][j][0]));
60         }
61     }
62     printf("%d\n",ans);
63     return 0;
64 }

 

bzoj 3791: 作业