BZOJ-1084: [SCOI2005]最大子矩阵(DP)

作者: AmadeusChan | 来源:发表于2018-11-29 11:12 被阅读0次

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1084

开始是以为是什么神题,后来发现m<=2那就直接DP O(n^3)水掉了。。。

代码:

#include <cstdio>

#include <algorithm>

#include <cstring>

 

using namespace std ;

 

#define rep( i , x )for(int i =0; i ++< x ;)

#define Rep( i , x )for(int i =0; i < x ;++ i )

 

const int maxn =110, maxm =3, maxk =15;

 

int n , m , k ;

 

 

void solve0(  ){

    int a[ maxn ], sum[ maxn ], f[ maxn ][ maxk ];

    bool u[ maxn ][ maxk ];

    sum[0]=0;

    rep( i , n ){

        scanf("%d", a + i );

        sum[ i ]= sum[ i -1]+ a[ i ];

    }

    memset( f ,0,sizeof( f ));

    memset( u ,false,sizeof( u ));

    u[0][0]=true;

    rep( i , n )Rep( j , k +1){

        if( u[ i -1][ j ]){

            u[ i ][ j ]=true, f[ i ][ j ]= f[ i -1][ j ];

        }

        if( j )Rep( x , i )if( u[ x ][ j -1]){

            u[ i ][ j ]=true;

            f[ i ][ j ]=max( f[ i ][ j ], f[ x ][ j -1]+ sum[ i ]- sum[ x ]);

        }

    }

    int ans =0;

    rep( i , n )if( u[ i ][ k ]) ans =max( ans , f[ i ][ k ]);

    printf("%d\n", ans );

}

 

int a[ maxn ][ maxm ], sum[ maxn ][ maxm ], f[ maxn ][ maxn ][ maxk ];

bool u[ maxn ][ maxn ][ maxk ];

 

void solve1(  ){

    sum[0][1]= sum[0][2]=0;

    rep( i , n ){

        scanf("%d%d",&a[ i ][1],&a[ i ][2]);

        sum[ i ][1]= sum[ i -1][1]+ a[ i ][1];

        sum[ i ][2]= sum[ i -1][2]+ a[ i ][2];

    }

    memset( f ,0,sizeof( f ));

    memset( u ,false,sizeof( u ));

    u[0][0][0]=true;

    Rep( i , n +1)Rep( j , n +1)if( i || j ){

        Rep( h , k +1){

            if( i )if( u[ i -1][ j ][ h ]){

                u[ i ][ j ][ h ]=true;

                f[ i ][ j ][ h ]= f[ i -1][ j ][ h ];

            }

            if( j )if( u[ i ][ j -1][ h ]){

                u[ i ][ j ][ h ]=true;

                f[ i ][ j ][ h ]=max( f[ i ][ j ][ h ], f[ i ][ j -1][ h ]);

            }

            if( h ){

                Rep( x , i )if( u[ x ][ j ][ h -1]){

                    u[ i ][ j ][ h ]=true;

                    f[ i ][ j ][ h ]=max( f[ i ][ j ][ h ], f[ x ][ j ][ h -1]+ sum[ i ][1]- sum[ x ][1]);

                }

                Rep( y , j )if( u[ i ][ y ][ h -1]){

                    u[ i ][ j ][ h ]=true;

                    f[ i ][ j ][ h ]=max( f[ i ][ j ][ h ], f[ i ][ y ][ h -1]+ sum[ j ][2]- sum[ y ][2]);

                }

                if( i == j )Rep( x , i )if( u[ x ][ x ][ h -1]){

                    u[ i ][ j ][ h ]=true;

                    f[ i ][ j ][ h ]=max( f[ i ][ j ][ h ], f[ x ][ x ][ h -1]+( sum[ i ][1]- sum[ x ][1])+( sum[ j ][2]- sum[ x ][2]));

                }

            }

        }

    }

    int ans =0;

    Rep( i , n +1)Rep( j , n +1)if( u[ i ][ j ][ k ]){

        ans =max( ans , f[ i ][ j ][ k ]);

    }

    printf("%d\n", ans );

}

 

int main(  ){

    scanf("%d%d%d",&n ,&m ,&k );

    if( m ==1)solve0(  );else solve1(  );

    return 0;

}

相关文章

  • BZOJ-1084: [SCOI2005]最大子矩阵(DP)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1084 开...

  • F - 6 HDU - 2830

    动态规划(dp):最大子矩阵

  • E - 5 HDU - 2870

    动态规划(dp):最大子矩阵

  • 题解 [SCOI2005]最大子矩阵

    题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不...

  • 最长连续子序和问题

    0X00 算法总结 最大子序和 53. 最大子序和 这是一道非常经典的 dp 问题, 以最大子序和的最后一个数字来...

  • 【5月】LeetCode:我怎么还是这么菜

    5.3 题目链接 53. 最大子序和 很喜欢的解法(DP) 官方解(分治) 参考题解:最大子序和 但是仔细观察「方...

  • 最大子矩阵

    之前学过最大子序列的求法:要求一个序列中和最大的连续的子序列,那么需要满足一下几步:1,子序列的第一个数大于1。2...

  • DP之最大子串

    1. a的n次幂,如何高效计算 2. 最大子串 考虑用dp,解决重复计算 2.1 DP要处理的一种情况是,新元素加...

  • unique-paths

    状态转移矩阵f[i][j]=f[i-1][j]+f[i][j-1]转换为一维dp[j]=dp[j]+dp[j-1]

  • 乘积最大子序列 -dp

    找出一个序列中乘积最大的连续子序列(至少包含一个数)。 样例样例 1: 输入:[2,3,-2,4]输出:6样例 2...

网友评论

    本文标题:BZOJ-1084: [SCOI2005]最大子矩阵(DP)

    本文链接:https://www.haomeiwen.com/subject/pfvxcqtx.html