bzoj 1296: [SCOI2009]粉刷匠

DP 每一层一个序列型DP,外面在套一个背包DP

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<queue>
 7 #include<algorithm>
 8 #include<vector>
 9 #define M 100
10 #define EPS 1e-10
11 #define ll long long
12 using namespace std;
13 ll read()
14 {
15     char ch=getchar();
16     ll x=0,f=1;
17     for(;ch<'0'||ch>'9';ch=getchar())
18         if(ch=='-')
19           f=-1;
20     for(;ch>='0'&&ch<='9';ch=getchar())
21         x=x*10+ch-'0';
22     return x*f;
23 }
24 int sum[M][2],n,m,t,f[M][M],g[M*M];
25 char ch[M];
26 void dp()
27 {
28   for(int i=1;i<=m;i++)
29     for(int j=1;j<=i;j++)
30       {
31         f[i][j]=0;
32         for(int k=i-1;k>=0;k--)
33           f[i][j]=max(f[i][j],f[k][j-1]+max(sum[i][1]-sum[k][1],sum[i][0]-sum[k][0]));
34       }
35 }
36 int main()
37 {
38    n=read();
39    m=read();
40    t=read();
41    scanf("%s",ch+1);
42    for(int i=1;i<=m;i++)
43      {
44        sum[i][0]=sum[i-1][0];
45        sum[i][1]=sum[i-1][1];
46        sum[i][ch[i]-'0']++;
47      }
48    dp();
49    for(int i=1;i<=min(m,t);i++)
50      g[i]=f[m][i];
51    for(int i=m+1;i<=t;i++)
52      g[i]=g[i-1];
53    for(int i=2;i<=n;i++)
54      {
55        scanf("%s",ch+1);
56        for(int i=1;i<=m;i++)
57          {
58            sum[i][0]=sum[i-1][0];
59            sum[i][1]=sum[i-1][1];
60            sum[i][ch[i]-'0']++;
61          }
62        dp();
63        for(int i=t;i;i--)
64          for(int j=1;j<=min(i,m);j++)
65            g[i]=max(g[i],g[i-j]+f[m][j]);
66      }
67    printf("%d
",g[t]);
68    return 0;
69 }
70 
原文地址:https://www.cnblogs.com/xiw5/p/5648697.html