洛谷 P2258 子矩阵
洛谷 P2258 子矩阵
Description
给出如下定义:
子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵。
例如,下面左图中选取第2、4行和第2、4、5列交叉位置的元素得到一个2*3的子矩阵如右图所示。9 3 3 3 9
9 4 8 7 4
1 7 4 6 6
6 8 5 6 9
7 4 5 6 1
的其中一个2*3的子矩阵是
4 7 4
8 6 9
相邻的元素:矩阵中的某个元素与其上下左右四个元素(如果存在的话)是相邻的。
矩阵的分值:矩阵中每一对相邻元素之差的绝对值之和。
本题任务:给定一个n行m列的正整数矩阵,请你从这个矩阵中选出一个r行c列的子矩阵,使得这个子矩阵的分值最小,并输出这个分值。
Input
第一行包含用空格隔开的四个整数n,m,r,c,意义如问题描述中所述,每两个整数之间用一个空格隔开。
接下来的n行,每行包含m个用空格隔开的整数,用来表示问题描述中那个n行m列的矩阵。
Output
- 输出共1行,包含1个整数,表示满足题目描述的子矩阵的最小分值。
Sample Input
5 5 2 3 9 3 3 3 9 9 4 8 7 4 1 7 4 6 6 6 8 5 6 9 7 4 5 6 1
Sample Output
6
题解:
- 搜索 + dp。
- 非常不错的一道题。
- 首先容易想到dp,于是提出dp(i, j, k, l)表示前i行取j行,取k列取l列的最小分值。
- 但是,我试着按照这个思路去写,越写越乱,然后就雾了。
- 那么,观察数据,n、m都很小。那么我们可以先用搜索枚举出选哪几行,然后再用dp处理选哪几列。那么dp数组就变成了dp(i, j)表示在搜索选出来的行条件下,前i列取j列的最小分值。
- 搞定。
- 但是,dp的边界细节很繁琐,要注意。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define N 25
using namespace std;int n, m, r, c, ans = 0x7fffffff;
int a[N][N], def1[N][N], dp[N][N];
int b[N], def2[N];
bool vis[N];void dfs(int dep)
{if(dep > r){memset(def1, 0, sizeof(def1));memset(def2, 0, sizeof(def2));for(int i = 2; i <= m; i++)for(int j = 1; j < i; j++)for(int k = 1; k <= r; k++){def1[i][j] += abs(a[b[k]][i] - a[b[k]][j]);def1[j][i] += abs(a[b[k]][i] - a[b[k]][j]);}for(int i = 1; i <= m; i++)for(int j = 1; j < r; j++)def2[i] += abs(a[b[j]][i] - a[b[j + 1]][i]);for(int i = 1; i <= m; i++)for(int j = 1; j <= min(c, i); j++){if(j == 1) dp[i][j] = def2[i];else if(j == i) dp[i][j] = dp[i - 1][j - 1] + def2[i] + def1[j - 1][i];else{dp[i][j] = 2e8;for(int k = j - 1; k < i; k++)dp[i][j] = min(dp[i][j], dp[k][j - 1] + def1[k][i] + def2[i]);}}for(int i = c; i <= m; i++) ans = min(ans, dp[i][c]);return;}for(int i = 1; i <= n; i++)if(!vis[i] && i > b[dep - 1]){vis[i] = 1;b[dep] = i;dfs(dep + 1);vis[i] = 0;}
}int main()
{cin >> n >> m >> r >> c;for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)cin >> a[i][j];dfs(1);cout << ans;return 0;
}
转载于:https://www.cnblogs.com/BigYellowDog/p/11620657.html
洛谷 P2258 子矩阵相关推荐
- 洛谷P2258 子矩阵[2017年5月计划 清北学堂51精英班Day1]
题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第2.4行和第2.4.5列交叉位置的元素 ...
- [T][3]洛谷 P2331 [SCOI2005] 最大子矩阵
题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 输入输出格式 输入格式: 第一行为n,m,k(1≤n≤100,1≤m≤2 ...
- 洛谷 P2331 [SCOI2005]最大子矩阵
PS:如果读过题了可以跳过题目描述直接到题解部分 提交链接:洛谷 P2331 [SCOI2005]最大子矩阵 题目 题目描述 这里有一个 n*m 的矩阵,请你选出其中 k 个子矩阵,使得这个 k 个子 ...
- 洛谷 - 试炼场(全部题目备份)
整理的算法模板合集: ACM模板 目录 1.新手村 1 - 1 洛谷的第一个任务 1 - 2 顺序与分支 1 - 3 循环!循环!循环! 1 - 4 数组 1 - 5 简单字符串 1 - 6 过程函数 ...
- 洛谷P3941入阵曲
洛谷P3941入阵曲 [题目描述] 丹青千秋酿,一醉解愁肠. 无悔少年枉,只愿壮志狂. 小 F 很喜欢数学,但是到了高中以后数学总是考不好. 有一天,他在数学课上发起了呆:他想起了过去的一年.一年前, ...
- 对于洛谷提高试炼场-动态规划篇的爆破
题外话 由于本蒟蒻的动态规划实在是太弱啦,所以有必要爆破一下洛谷提高试炼场.里面有很多非常好,难度也合适的动态规划题--(然而你还是抄了不少题解) niconiconi~让我们一起开始爆破吧. lv- ...
- 洛谷[P1719 最大加权矩形] {前缀和与差分} 奋斗的珂珂~
洛谷[P1719 最大加权矩形] {前缀和与差分} 题目描述 为了更好的备战NOIP2013,电脑组的几个女孩子LYQ,ZSC,ZHQ认为,我们不光需要机房,我们还需要运动,于是就决定找校长申请一块电 ...
- 洛谷-题解 P2672 【推销员】
独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...
- 洛谷 P1142 轰炸
洛谷 P1142 轰炸 题目描述 "我该怎么办?"飞行员klux向你求助. 事实上,klux面对的是一个很简单的问题,但是他实在太菜了. klux要想轰炸某个区域内的一些地方,它们 ...
最新文章
- java 有序set_Java 从Set里面取出有序的记录详解及实例
- [css] 怎么IE6下在使用margin:0 auto;无法使其居中?
- c#提交事务的两种方法
- C语言编程数出1到100的整数中出现了多少次数字9
- windows apache 负载均衡配置 Tomcat集群配置
- 八卦图代码matlab,12行javascript代码绘制一个八卦图_javascript技巧
- android 知识点大全 面试
- PS常用快捷键及模板使用
- Intellij IDEA设置类的文件头注释(@Author)(一)
- matlab设计误码率,通信原理课程设计报告 数字传输系统误码率测试器的matlab实现及性能分析...
- 线程池的好处,详解,单例(绝对好记)
- 揭秘可变剪切研究的本质
- 可积 连续 可微 可导关系
- 好文分享 努力从何时开始都不晚 跟自己比 不断进步
- 链路追踪工具 skywalking
- 《神经科学:探索脑》学习笔记(第13章 运动的脊髓控制)
- 葫芦娃六娃_盘点《葫芦娃》中真正的实力排行,千里眼排第二,火娃排第四
- C#深入学习--委托
- YOLO—神经网络原理
- props 和 state的区别
热门文章
- KRKR基础篇(一)
- Abracadabra
- vue发送请求时遇到index.vue6ced90 Uncaught (in promise) TypeError Cannot read properties of undefined
- 开始记录深度学习工作站的学习之路
- 视频 | 自动化测试[1小时]免费领取
- 新款智能枕头为人们的生活带来更佳体验
- linux的lib目录,Linux 目录结构:/lib 分析
- 管家婆软件分销ERP D9学习资料
- 构建乘积数组[前后缀优化]
- Python获取全部股票代码信息(A/B/H/美/英股)