每日一题 [SCOI2005]最大子矩阵 (多维dp)

[SCOI2005]最大子矩阵

https://ac.nowcoder.com/acm/problem/20242

一.题意

n * m 的矩阵分成 k 组互不重叠的矩阵,求最大的子矩阵和。

二.题解

特别注意到的是 m 的值为 1 或者 2,所以可以由比较简单的方法写出。
考虑 代表第一列前 i 个元素和第二列前 j 个元素组成 k 个矩阵的最大值。
有以下的递推方程:

  1. 由前一状态推出,
  2. 枚举第一列,
  3. 枚举第二列,
  4. 当第一列和第二列取同样多的元素可以考虑合并,

三.代码:

#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ld long double
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define inf 0x3f3f3f3f
#define io std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;

const int manx=1e6+5;
const int N=1e3+5;
const int mod=1e9+7;

ll s[N][3],dp[N][N][15];
ll n,m,ans,k,x;

int main(){
    io; cin>>n>>m>>k; ll K=k;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>x,s[i][j]=s[i-1][j]+x;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=K;k++){
                dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k]);
                for(int l=0;l<i;l++) 
                    dp[i][j][k]=max(dp[i][j][k],dp[l][j][k-1]+s[i][1]-s[l][1]);
                for(int l=0;l<j;l++) 
                    dp[i][j][k]=max(dp[i][j][k],dp[i][l][k-1]+s[j][2]-s[l][2]);
                if(i==j)
                    for(int l=0;l<i;l++)
                        dp[i][j][k]=max(dp[i][j][k],dp[l][l][k-1]+s[i][1]+s[j][2]-s[l][1]-s[l][2]);
            }
    cout<<dp[n][n][K];
    return 0;
}
全部评论

相关推荐

offer多多的六边形战士很无语:看了你的博客,感觉挺不错的,可以把你的访问量和粉丝数在简历里提一下,闪光点(仅个人意见)
点赞 评论 收藏
分享
像好涩一样好学:这公司我也拿过 基本明确周六加班 工资还凑活 另外下次镜头往上点儿
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务