bzoj 1084: [SCOI2005]最大子矩阵

 1 #include<cstdio>
 2 #include<iostream>
 3 #define M 102
 4 using namespace std;
 5 int f1[M][M],sum[M],sum1[M],n,m,K,f[M][M][12];
 6 int main()
 7 {
 8     scanf("%d%d%d",&n,&m,&K);
 9     if(m==1)
10       {
11         for(int i=1;i<=n;i++)
12           {
13             int a1;
14             scanf("%d",&a1);
15             sum[i]=sum[i-1]+a1;
16           }
17         for(int i=1;i<=n;i++)
18           for(int j=1;j<=K;j++)
19             {
20                f1[i][j]=f1[i-1][j];
21                for(int l=0;l<=i;l++)
22                 f1[i][j]=max(f1[i][j],f1[l][j-1]+sum[i]-sum[l]);    
23             }       
24         printf("%d\n",f1[n][K]);
25       }
26     else
27       {
28  
29         for(int i=1;i<=n;i++)
30           {
31             int a1,a2;
32             scanf("%d%d",&a1,&a2);
33             sum[i]=sum[i-1]+a1;
34             sum1[i]=sum1[i-1]+a2;
35             }
36         for(int i=1;i<=n;i++)
37           for(int j=1;j<=n;j++)
38             for(int k=1;k<=K;k++)
39               {
40                 f[i][j][k]=max(f[i-1][j][k],f[i][j-1][k]);
41                 for(int l=0;l<i;l++)
42                   f[i][j][k]=max(f[i][j][k],f[l][j][k-1]+sum[i]-sum[l]);
43                 for(int l=0;l<j;l++)
44                   f[i][j][k]=max(f[i][j][k],f[i][l][k-1]+sum1[j]-sum1[l]);
45                 if(i==j)
46                   for(int l=0;l<i;l++)
47                     f[i][j][k]=max(f[i][j][k],f[l][l][k-1]+sum[i]-sum[l]+sum1[j]-sum1[l]);
48               }
49         printf("%d\n",f[n][n][K]);
50       }
51     return 0;
52 }

一看貌似状压dp,但我的状压非常弱,注意到题目中的m只有1或2,可以分开讨论,两种dp。两行的时候,可以先第一行dp,再第二行dp,如果i==j,进行取两行的dp。

你可能感兴趣的:(bzoj 1084: [SCOI2005]最大子矩阵)