题目描述

给出如下定义:

  1. 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵。

例如,下面左图中选取第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

  1. 相邻的元素:矩阵中的某个元素与其上下左右四个元素(如果存在的话)是相邻的。

  2. 矩阵的分值:矩阵中每一对相邻元素之差的绝对值之和。

本题任务:给定一个n行m列的正整数矩阵,请你从这个矩阵中选出一个r行c列的子矩阵,使得这个子矩阵的分值最小,并输出这个分值。

(本题目为2014NOIP普及T4)

输入输出格式

输入格式:

第一行包含用空格隔开的四个整数n,m,r,c,意义如问题描述中所述,每两个整数之间用一个空格隔开。

接下来的n行,每行包含m个用空格隔开的整数,用来表示问题描述中那个n行m列的矩阵。

输出格式:

输出共1行,包含1个整数,表示满足题目描述的子矩阵的最小分值。

输入输出样例

输入样例#1:

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

输出样例#1:

6

输入样例#2:

7 7 3 3
7 7 7 6 2 10 5
5 8 8 2 1 6 2
2 9 5 5 6 1 7
7 9 3 6 1 7 8
1 9 1 4 7 8 8
10 5 9 1 1 8 10
1 3 1 5 4 8 6

输出样例#2:

16

说明

【输入输出样例1说明】

该矩阵中分值最小的2行3列的子矩阵由原矩阵的第4行、第5行与第1列、第3列、第4列交叉位置的元素组成,为

6 5 6

7 5 6

,其分值为

|6−5| + |5−6| + |7−5| + |5−6| + |6−7| + |5−5| + |6−6| =6。

【输入输出样例2说明】

该矩阵中分值最小的3行3列的子矩阵由原矩阵的第4行、第5行、第6行与第2列、第6列、第7列交叉位置的元素组成,选取的分值最小的子矩阵为

9 7 8 9 8 8 5 8 10

【数据说明】

对于50%的数据,1 ≤ n ≤ 12,1 ≤ m ≤ 12,矩阵中的每个元素1 ≤ a[i][j] ≤ 20;

对于100%的数据,1 ≤ n ≤ 16,1 ≤ m ≤ 16,矩阵中的每个元素1 ≤ a[i][j] ≤ 1,000,

1 ≤ r ≤ n,1 ≤ c ≤ m。

枚举一部分,dp一部分

枚举选的行

令dp[i][j]表示前i列选j列且第i列必须被选的最小值

col1[i]  表示所选行中,列内的差值的绝对值之和

col2[i][j] 表示所选行中,第i列与第j列差值的绝对值之和

转移dp[i][j] = min(dp[i][j], do[k][j - 1] + col1[i] + col2[k][i]),其中k < i

有一些细节需要注意(见代码)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a,b) ((a) > (b) ? (b) : (a))
#define lowbit(a) ((a) & (-(a)))int read()
{int x = 0;char ch = getchar();char c = ch;while(ch > '9' || ch < '0')c = ch, ch = getchar();while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();if(c == '-')return -x;return x;
}
const int INF = 0x3f3f3f3f;
const int MAXN = 16 + 5;
const int MAXM = 16 + 5;int n,m;
int g[MAXN][MAXM];
int col2[MAXN][MAXN];
int col1[MAXM];
int r,c;
int dp[MAXN][MAXM];//dp[i][j]表示前i列选j行且第i列一定会被选 int ans;
bool b[MAXN];
int num[MAXN];int dpp();void dfs(int step, int pre)
{if(step > r){ans = min(ans, dpp());return;}for(int i = pre + 1;i <= n;i ++){if(!b[i]){num[step] = i;b[i] = true;dfs(step + 1, i);num[step] = 0;b[i] = false;}}
}int dpp()
{memset(col2, 0, sizeof(col2));memset(col1, 0, sizeof(col1));memset(dp, 0, sizeof(dp));for(int i = 2;i <= r;i ++){for(int j = 1;j <= m;j ++){col1[j]  += abs(g[num[i]][j] - g[num[i - 1]][j]);}}for(int i = 1;i <= m;i ++){for(int j = i + 1;j <= m;j ++){for(int k = 1;k <= r;k ++){col2[i][j] += abs(g[num[k]][i] - g[num[k]][j]);col2[j][i] += abs(g[num[k]][i] - g[num[k]][j]);}}}for(int i = 1;i <= m;i ++){for(int j = 1;j <= c && j <= i;j ++)//注意j <= i{dp[i][j] = INF;for(int k = j - 1;k < i;k ++)//注意k = j - 1{dp[i][j] = min(dp[k][j - 1] + col2[k][i] + col1[i], dp[i][j]);}}}int re = INF;for(int i = c;i <= m;i ++){re = min(re, dp[i][c]);}return re;
}inline void init()
{n = read();m = read();r = read();c = read();for(int i = 1;i <= n;i ++){for(int j = 1;j <= m;j ++){g[i][j] = read();}}ans = INF;
}
inline void put()
{printf("%d", ans);
}int main()
{init();dfs(1, 0);put();return 0;
}

转载于:https://www.cnblogs.com/huibixiaoxing/p/6894495.html

洛谷P2258 子矩阵[2017年5月计划 清北学堂51精英班Day1]相关推荐

  1. 洛谷P2327 [SCOI2005]扫雷 [2017年5月计划 清北学堂51精英班Day1]

    P2327 [SCOI2005]扫雷 题目描述 输入输出格式 输入格式: 第一行为N,第二行有N个数,依次为第二列的格子中的数.(1<= N <= 10000) 输出格式: 一个数,即第一 ...

  2. 洛谷P2073 送花 [2017年6月计划 线段树01]

    P2073 送花 题目背景 小明准备给小红送一束花,以表达他对小红的爱意.他在花店看中了一些花,准备用它们包成花束. 题目描述 这些花都很漂亮,每朵花有一个美丽值W,价格为C. 小明一开始有一个空的花 ...

  3. 洛谷 P2258 子矩阵

    洛谷 P2258 子矩阵 Description 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取 ...

  4. 2017国庆 济南清北学堂 8天乐

    Day 0 想吐槽济南的堵车 大约接近4点从莱芜走的,走高速一个多小时,5点左右就到了济南,但是因为济南的堵车,下班高峰期,用了两个多小时才到了我们的目的地.好不容易到宾馆登记了,mc还要我们开会,8 ...

  5. 洛谷P2429 制杖题 [2017年6月计划 数论10]

    P2429 制杖题 题目描述 求不大于 m 的. 质因数集与给定质数集有交集的自然数之和. 输入输出格式 输入格式: 第一行二个整数 n,m. 第二行 n 个整数,表示质数集内的元素 p[i]. 输出 ...

  6. 洛谷P1474 [USACO 2.3]货币系统 Money Systems [2017年4月计划 动态规划04]

    P1474 货币系统 Money Systems 题目描述 母牛们不但创建了它们自己的政府而且选择了建立了自己的货币系统.由于它们特殊的思考方式,它们对货币的数值感到好奇. 传统地,一个货币系统是由1 ...

  7. 洛谷P2826 [USACO08NOV]光开关Light Switching [2017年6月计划 线段树02]

    P2826 [USACO08NOV]光开关Light Switching 题目描述 Farmer John tries to keep the cows sharp by letting them p ...

  8. 洛谷P1757 通天之分组背包 [2017年4月计划 动态规划06]

    P1757 通天之分组背包 题目背景 直达通天路·小A历险记第二篇 题目描述 自01背包问世之后,小A对此深感兴趣.一天,小A去远游,却发现他的背包不同于01背包,他的物品大致可分为k组,每组中的物品 ...

  9. 题解——洛谷 P2680 NOIP提高组 2015 运输计划

    树上差分加上二分答案 详细题解待填坑 #include <cstdio> #include <algorithm> #include <cstring> using ...

最新文章

  1. 信号量,互斥锁,条件变量的联系与区别
  2. WPF 4 Ribbon 开发 之 应用程序菜单(Application Menu)
  3. sourceTree安装与使用
  4. 列表_月隐学python第6课
  5. 万用表怎么测量电池容量_家电常识丨万用表的测量应用学习
  6. 7.6 yum更换国内源 7.7 yum下载rpm包 7.8/7.9 源码包安装
  7. EntityFramework Core上下文实例池原理
  8. 谷歌 colab_如何在Google Colab上使用熊猫分析
  9. 时间戳转中国人能看得懂的日期格式 yy-mm-dd
  10. ARIS业务流程建模工具培训
  11. windows 7系统报错txupd.exe
  12. ti嵌入式linux设计外包,基于嵌入式Linux的PMP系统设计与实现
  13. c语言谭浩强简介,大一C语言谭浩强总结(到数组)简介.ppt
  14. 工序能力指数Cp判定标准(附免费CPK计算工具)
  15. C++ 自定义新的运算符
  16. kali安装openvas全过程
  17. 非常好用的开源矢量地图切片工具
  18. 我的RUST学习——【第九章 9-1】panic! 与不可恢复的错误
  19. 那位学软件测试的广州宝妈,后来怎样了?
  20. OVS CT连接追踪实现NAT

热门文章

  1. PDF页面删除怎么操作
  2. mapbox-gl加载three.js泛光效果(视频)
  3. 政策热市场冷 中国新能源汽车遇尴尬
  4. 利用文件保存数据(c语言)
  5. 怎样把PDF翻译成中文
  6. 问题 I: 锤子剪刀布 (20)
  7. 技术人员硬实力和软实力
  8. TCP/IP详解--拥塞控制机制 RTT时间计算相关的算法
  9. python爬取微信小程序源代码_【实战】CrawlSpider实现微信小程序社区爬虫
  10. 理解物理 CPU 与逻辑 CPU