题目链接:传送门

题目:

题目描述

这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大。注意:选出的k个子矩阵不能相互重叠。
输入输出格式
输入格式: 第一行为n,m,k(≤n≤,≤m≤,≤k≤),接下来n行描述矩阵每行中的每个元素的分值(每个元素的分值的绝对值不超过32767)。 输出格式: 只有一行为k个子矩阵分值之和最大为多少。 输入输出样例
输入样例#: 复制 - - 输出样例#: 复制

PS:好像有很多类似的题目,上次的那道中国象棋(放炮的)也是,都是分类讨论多种情况就好了。

思路:

注意到m ≤ 2,所以可以按行dp,分类讨论转移的情况。

  ① 当前行不选;

  ② 当前行选左边;

  ③ 当前行选右边;

  ④ 当前行两个都选,但是作为两个矩阵;

  ⑤ 当前行两个都选,作为同一个矩阵;

以上的m = 2时的情况,m = 1时更简单,只有选或者不选,就不赘述了。

状态:

  f[i][j][k] 表示当前第i行,构造了j个矩阵,当前行的状态为k,(k = 0 - 4对应上面的① - ⑤)

状态转移方程很容易得出,见代码。

时间复杂度是O(NM4K)

#include <bits/stdc++.h>

using namespace std;
const int INF = 0x3f3f3f3f;
const int MAX_N = + ;
const int MAX_M = + ;
const int MAX_K = + ; inline void tomax(int&a, int b)
{
a = max(a, b);
} int mat[MAX_N][MAX_M];
int f[MAX_N][MAX_K][]; int main()
{
int N, M, K;
cin >> N >> M >> K;
for (int i = ; i <= N; i++)
for (int j = ; j <= M; j++)
scanf("%d", &mat[i][j]);
memset(f, -INF, sizeof f);
for (int i = ; i <= N; i++)
for (int j = ; j <= K; j++)
f[i][j][] = ;
if (M == ) {
for (int i = ; i <= N; i++)
for (int j = ; j <= K; j++) {
tomax(f[i][j][], f[i-][j][]);
tomax(f[i][j][], f[i-][j][]);
if (j- >= )
tomax(f[i][j][], f[i-][j-][]);
tomax(f[i][j][], f[i-][j][]);
f[i][j][] += mat[i][];
}
cout << max(f[N][K][], f[N][K][]) << endl;
return ;
}
for (int i = ; i <= N; i++) {
for (int j = ; j <= K; j++) {
for (int k = ; k <= ; k++) {
//0:当前行不选
tomax(f[i][j][], f[i-][j][k]);
//1:当前行选左边
if ((k == || k == || k == ) && (j- >= ))
tomax(f[i][j][], f[i-][j-][k]);
else if (k == || k == )
tomax(f[i][j][], f[i-][j][k]);
//2:当前行选右边
if ((k <= || k == ) && j- >= )
tomax(f[i][j][], f[i-][j-][k]);
else if (k == || k == )
tomax(f[i][j][], f[i-][j][k]);
//3:当前行左右都选(分开)
if ((k == || k == ) && j- >= )
tomax(f[i][j][], f[i-][j-][k]);
else if ((k == || k == ) && j- >= )
tomax(f[i][j][], f[i-][j-][k]);
else if (k == )
tomax(f[i][j][], f[i-][j][k]);
//4:当前行左右都选(一起的)
if (k != && j- >= )
tomax(f[i][j][], f[i-][j-][k]);
else if (k == )
tomax(f[i][j][], f[i-][j][k]);
}
f[i][j][] += mat[i][];//1:当前行选左边
f[i][j][] += mat[i][];//2:当前行选右边
f[i][j][] += mat[i][] + mat[i][];//3:当前行左右都选(分开)
f[i][j][] += mat[i][] + mat[i][];//4:当前行左右都选(一起的)
}
}
int ans = -INF;
for (int k = ; k <= ; k++)
tomax(ans, f[N][K][k]);
cout << ans;
return ;
}
/*
3 1 2
1
-1
2
*/

P2331 [SCOI2005]最大子矩阵 (动规:分类讨论状态)的更多相关文章

  1. 洛谷P2331 [SCOI2005]最大子矩阵 DP

    P2331 [SCOI2005]最大子矩阵 题意 : 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 第一行为n,m,k(1≤n≤ ...

  2. 洛谷P2331 [SCOI2005] 最大子矩阵[序列DP]

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

  3. luogu P2331 [SCOI2005]最大子矩阵

    传送门 \[\huge\mathit{warning}\] \[\small\text{以下说明文字高能,请心脏病,,,,,,人士谨慎观看,请未成年人在家长陪同下观看}\] 皮这一下很开心 其实是代码 ...

  4. 洛谷 P2331 [SCOI2005]最大子矩阵

    洛谷 这一题,乍一眼看上去只想到了最暴力的暴力--大概\(n^4\)吧. 仔细看看数据范围,发现\(1 \leq m \leq 2\),这就好办了,分两类讨论. 我先打了\(m=1\)的情况,拿了30 ...

  5. P2331 [SCOI2005]最大子矩阵

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

  6. 洛谷P2331[SCOI2005]最大子矩阵

    题目 DP 此题可以分为两个子问题. \(m\)等于\(1\): 原题目转化为求一行数列里的\(k\)块区间的和,区间可以为空的值. 直接定义状态\(dp[i][t]\)表示前i个数分为t块的最大值. ...

  7. 【BZOJ1088】[SCOI2005] 扫雷Mine(分类讨论)

    点此看题面 大致题意: 给你一个\(2*n\)的扫雷棋盘,现让你根据第二列的信息确定第一列有多少种摆法. 扫雷性质 听说这是一道动态规划+数学题. 其实,根据扫雷游戏的某个性质,只要确定了第一个格子是 ...

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

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

  9. 1084: [SCOI2005]最大子矩阵

    1084: [SCOI2005]最大子矩阵 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1325  Solved: 670[Submit][Stat ...

随机推荐

  1. Easyui的datagrid的行编辑器Editor中添加事件(修改某个单元格带出其他单元格的值)

    项目中有个datagrid需要编辑行时,用到Editor的属性,那么如何添加一个事件 问题:同一个编辑行中的某个单元格值改变时,修改其他单元格的值 页面用到的datagrid <table id ...

  2. C++中类的静态成员与实例成员的区别

    C++中类的静态成员与实例成员的区别 1.有static修饰的成员变量或成员函数称为静态成员. 2.在内存中,类的静态数据成员占有一块特定的内存空间,被该类的所有实例(对象)共享.而同一个类的不同对象 ...

  3. Win10系列:UWP界面布局进阶6

    在Windows 10的"个性化设置"中,用户可以更改计算机在锁屏状态下的背景图片,除此之外,也可以通过Windows应用商店应用程序将喜欢的图片设置为锁屏背景,下面通过一个示例来 ...

  4. Win10系列:WinJS库控件

    在介绍了如何使用标准的HTML控件以及WinJS库中提供的新控件之后,下面来着重介绍WinJS库中几种常用的控件. (1)ListView控件 在开发Windows应用商店应用时可以使用ListVie ...

  5. 正则:img的url,width,height 和 a标签的url以及替换

    代码:// 内容:$detail['content'] //img的url,width,height $img = array(); $matches = array(); $regeImg = '/ ...

  6. c算法:字符串查找-KMP算法

    /* *用KMP算法实现字符串匹配搜索方法 *该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的 *字符串匹配,如果匹配,则输出文件名:包含该字符串的行 *待搜索的目标串搜索指针移动位数 = ...

  7. 强化学习4-时序差分TD

    之前讲到强化学习在不基于模型时可以用蒙特卡罗方法求解,但是蒙特卡罗方法需要在每次采样时生产完整序列,而在现实中,我们很可能无法生成完整序列,那么又该如何解决这类强化学习问题呢? 由贝尔曼方程 vπ(s ...

  8. android小程序-电子钢琴-滑动连续响应

    原创文字,转载请标明出处: 利用Button实现简单地电子钢琴,可以简单地响应按钮的click事件来发出相应的声音.但是这样不能达到手指在屏幕滑动,而连续发声的效果,就像手指在真实钢琴按键上滑过一样. ...

  9. django做redis缓存

    django中应用redis:pip3 install django-redis - 配置 CACHES = { "default": { "BACKEND": ...

  10. VSFTP服务配置

    FTP连接及传输模式控制连接:TCP 21 ,用于发送FTP命令信息数据连接:TCP 20 ,用于上传.下载数据数据连接的建立类型:主动模式.被动模式 主动模式:服务器主动发起数据连接·首先由客户端向 ...