欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ1084


题意概括

  这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。

  输入:第一行为n,m,k(1≤n≤100,1≤m≤2,1≤k≤10),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。


题解

  注意到1<=m<=2!

  如果m = 1 ,那么就是一个简单的线性dp。

  我们设dp[i][j]表示在前i个里面选出k个子矩阵的最大分值。

  那么分两种情况讨论:

  1.  什么都不干: dp[i][j] = max(dp[i][j], dp[i-1][j])

  2. 弄一个新的子矩阵: dp[i][j] = max(dp[i][j], dp[x][j - 1] + presum[i] - presum[x])  0<=x<i

  时间复杂度O(kn2)

  如果 m = 2 ,那么是一个稍微复杂一点的线性dp。

  我们设dp[i][j][x]表示在第一列的前i个和第二列的前j个里面选出x个子矩阵的最大分值。

  那么分几种情况进行讨论:

  1. 什么都不干: dp[i][j][x] = max(dp[i][j][x], dp[i - 1][j][x], dp[i][j - 1][x])

  2. 在第一列弄一个新的子矩阵: dp[i][j][x] = max(dp[i][j][x], dp[y][j][x - 1] + presum[i][1] - presum[y][1])  0<=y<i

  3. 在第二列弄一个新的子矩阵: dp[i][j][x] = max(dp[i][j][x], dp[i][y][x - 1] + presum[j][2] - presum[y][2])  0<=y<j

  4. 在第一、二列弄一个宽度为2的子矩阵: dp[i][j][x] = max(dp[i][j][x], dp[y][y][x - 1] + presum[i][1] - presum[y][1] + presum[j][2] - presum[y][2])  i = j 且 0<=y<i

  时间复杂度O(kn3)


代码

#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <cmath>
using namespace std;
const int N=+,M=,K=+;
const int Inf=<<;
int n,m,k,a[N][M];
void solve1(){
int dp[N][K],presum[N];
for (int i=;i<N;i++)
for (int j=;j<K;j++)
dp[i][j]=-Inf;
presum[]=;
for (int i=;i<=n;i++)
presum[i]=presum[i-]+a[i][];
dp[][]=;
int ans=-Inf;
for (int i=;i<=n;i++)
for (int j=;j<=k;j++){
if (!i&&!j)
continue;
if (i)
dp[i][j]=dp[i-][j];
if (!j)
continue;
for (int x=;x<i;x++)
dp[i][j]=max(dp[i][j],dp[x][j-]+presum[i]-presum[x]);
}
printf("%d",dp[n][k]);
}
void solve2(){
int dp[N][N][K],presum[N][M];
presum[][]=presum[][]=;
for (int i=;i<=n;i++){
presum[i][]=presum[i-][]+a[i][];
presum[i][]=presum[i-][]+a[i][];
}
for (int i=;i<N;i++)
for (int j=;j<N;j++)
for (int x=;x<K;x++)
dp[i][j][x]=-Inf;
dp[][][]=;
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
for (int x=;x<=k;x++){
if (!i&&!j&&!x)
continue;
if (i&&j)
dp[i][j][x]=max(dp[i-][j][x],dp[i][j-][x]);
else if (i)
dp[i][j][x]=dp[i-][j][x];
else if (j)
dp[i][j][x]=dp[i][j-][x];
if (!x)
continue;
for (int y=;y<i;y++)
dp[i][j][x]=max(dp[i][j][x],dp[y][j][x-]+presum[i][]-presum[y][]);
for (int y=;y<j;y++)
dp[i][j][x]=max(dp[i][j][x],dp[i][y][x-]+presum[j][]-presum[y][]);
if (i==j)
for (int y=;y<i;y++)
dp[i][j][x]=max(dp[i][j][x],dp[y][y][x-]+presum[i][]-presum[y][]+presum[j][]-presum[y][]);
}
printf("%d",dp[n][n][k]);
}
int main(){
scanf("%d%d%d",&n,&m,&k);
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
scanf("%d",&a[i][j]);
if (m==)
solve1();
else
solve2();
return ;
}

BZOJ1084 [SCOI2005]最大子矩阵 动态规划的更多相关文章

  1. [bzoj1084][SCOI2005]最大子矩阵_动态规划_伪·轮廓线dp

    最大子矩阵 bzoj-1084 SCOI-2005 题目大意:给定一个n*m的矩阵,请你选出k个互不重叠的子矩阵使得它们的权值和最大. 注释:$1\le n \le 100$,$1\le m\le 2 ...

  2. bzoj千题计划198:bzoj1084: [SCOI2005]最大子矩阵

    http://www.lydsy.com/JudgeOnline/problem.php?id=1084 m=1: dp[i][j] 前i个数,选了j个矩阵的最大和 第i个不选:由dp[i-1][j] ...

  3. bzoj1084: [SCOI2005]最大子矩阵 dp

    这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 题解:m很小分类讨论,m==1时怎么搞都可以,m==2时,dp[i][j][k]表 ...

  4. BZOJ 1084 [SCOI2005]最大子矩阵 - 动态规划

    传送门 题目大意: 从矩阵中取出k个互不重叠的子矩阵,求最大的和. 题目分析: 对于m=1,直接最大m子段和. 对于m=2: \(dp[i][j][k]\)表示扫描到第一列i和第2列j时选取了k个矩阵 ...

  5. bzoj1084: [SCOI2005]最大子矩阵

    dp.状态转移方程在代码里 #include<cstdio> #include<algorithm> #include<cstring> using namespa ...

  6. BZOJ1084 SCOI2005最大子矩阵

    考虑DP f[i][j][k]表示一行到i一行到j共取k块最大值,类似于最长公共子序列n^2那种 注意相等时可以一起拿 By:大奕哥 #include<bits/stdc++.h> usi ...

  7. [SCOI2005]最大子矩阵 (动态规划)

    题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 输入输出格式 输入格式: 第一行为n,m,k(1≤n≤100,1≤m≤2 ...

  8. bzoj1084 [SCOI2005]最大子矩阵——背包

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1084 水题...分类讨论一下即可. 代码如下: #include<iostream&g ...

  9. [bzoj1084][SCOI2005]最大子矩阵(DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1084 分析: m=1时:相当于只有一行数,让你取出p段,使得总和最大 明显可以DP,f ...

随机推荐

  1. Linux之Ubuntu安装搜狗输入法

    1.下载搜狗输入法安装包 搜狗官网:https://pinyin.sogou.com/linux/ 2.更新ubuntu内置的包管理器apt-get的软件源[如果中途安装失败,经常是此原因造成的] s ...

  2. python之functools partial

    from functools import partial def aa(a,b,c): print ('a :',a) print ('b :',b) print ('c :',c) bb=part ...

  3. mysql架构解读~mysql的多源复制

    一 场景需求 多源复制版本 5.7,目标主机5.6.21 4个DB机器的某些数据库需要数据汇总进行连表查询 二 进行搭建  1 导出相应的目的库     mysqldump -uuser -ppass ...

  4. 课程2:《黑马程序员_Java基础视频-深入浅出精华版》-视频列表-

    \day01\avi\01.01_计算机基础(计算机概述).avi; \day01\avi\01.02_计算机基础(计算机硬件和软件概述).avi; \day01\avi\01.03_计算机基础(软件 ...

  5. 【python图像处理】图像的缩放、旋转与翻转

    [python图像处理]图像的缩放.旋转与翻转 图像的几何变换,如缩放.旋转和翻转等,在图像处理中扮演着重要的角色,python中的Image类分别提供了这些操作的接口函数,下面进行逐一介绍. 1.图 ...

  6. Linux的capability深入分析(2)【转】

    转自:https://blog.csdn.net/wangpengqi/article/details/9821231 rpm -ql libcap-2.16-5.2.el6.i686  /lib/l ...

  7. C++ virtual函数重写,在继承的时候没有在函数前写virtual关键字也依然是虚函数吗?

    比如: class Base { Base() {}; ~Base() {}; virtual void Init(); }; class Derived:public Base { virtual ...

  8. 带你玩转Visual Studio——带你理解微软的预编译头技术

    原文地址:http://blog.csdn.net/luoweifu/article/details/49010627 不陌生的stdafx.h 还记得带你玩转Visual Studio——带你新建一 ...

  9. ubuntu数据库迁移

    环境:ubuntu16.04 简介:本教程演示如何从旧数据库服务器服转移到另一个新服务器. 场景:假设你有自己的云服务器安装了WordPress站点,你为了更多的内存和处理能力想升级到新的服务器. 操 ...

  10. python 语言特性

    动态强类型: 动态类型语言:在运行期进行类型检查的语言,也就是在编写代码的时候可以不指定变量的数据类型,比如Python和Ruby 静态类型语言:它的数据类型是在编译期进行检查的,也就是说变量在使用前 ...