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\n",g[t]); 68 return 0; 69 } 70