zoukankan      html  css  js  c++  java
  • NOIP2014-普及组复赛-第四题-子矩阵

    题目描述 Description
    给出如下定义:

        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

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

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

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


    (本题目为2014NOIP普及T4)
     输入输出格式 Input/output
    输入格式:
    第一行包含用空格隔开的四个整数n,m,r,c,意义如问题描述中所述,每两个整数之间用一个空格隔开。

        接下来的n行,每行包含m个用空格隔开的整数,用来表示问题描述中那个n行m列的矩阵。
    输出格式:
    输出共1行,包含1个整数,表示满足题目描述的子矩阵的最小分值。
     输入输出样例 Sample input/output
    样例测试点#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

    输出样例:

    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

    输出样例:

    16

    说明 description
    【输入输出样例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。
    思路:这题实在太难,不会......
    代码如下:
      1 #include       <map>  
      2 #include       <set>  
      3 #include     <stack>
      4 #include     <cmath>  
      5 #include     <ctime>  
      6 #include     <queue>  
      7 #include    <cstdio>  
      8 #include    <vector>  
      9 #include    <string>  
     10 #include    <bitset>  
     11 #include   <cstring>  
     12 #include   <cstdlib>  
     13 #include  <iostream>  
     14 #include <algorithm>  
     15 using namespace std;  
     16 
     17 #ifndef unix  
     18     #define lld "%I64d"  
     19     #define llu "%I64u"  
     20 #else  
     21     #define lld "%lld"  
     22     #define llu "%llu"  
     23 #endif  
     24 
     25 #define FOR(a,b,c)  for(int (a)=b;(a)<=(c);++(a))  
     26 #define FORD(a,b,c) for(int (a)=b;(a)>=(c);--(a))  
     27 #define FORV(a,t,b) for(vector<t>::iterator a=b.begin();a!=b.end();++a)  
     28 #define MAX(a,b)                   a=max(a,b)  
     29 #define MIN(a,b)                   a=min(a,b)  
     30 #define BLA                      printf("
    ")  
     31 #define pb                          push_back  
     32 #define mp                          make_pair  
     33 #define gc                            getchar  
     34 #define RT                             return  
     35 #define BB                             second  
     36 #define AA                              first  
     37 #define bk                              break  
     38 #define LINF             0x3f3f3f3f3f3f3f3fll  
     39 #define INF                        0x3f3f3f3f  
     40 #define eps                              1e-8  
     41 #define DINF                             1e20  
     42 
     43 //#define Generator  
     44 
     45 typedef long long           ll;  
     46 typedef unsigned            ui;  
     47 typedef unsigned long long ull;  
     48 typedef pair<int,int>      pii;  
     49 typedef pair<ll ,ll >      pll;  
     50 
     51 const int MAXN= 0;  
     52 const int MOD = 0;  
     53 
     54 template <class T> inline void CLR(T &g)             {T t;swap(t,g);}  
     55 template <class T> inline void CLR(T &g,int a){memset(g,a,sizeof g);}  
     56 template <class T> inline void CPY(T &a,T &b) {memcpy(a,b,sizeof a);}  
     57 template <class T> inline bool inr(T a,T b,T c)  {RT (a>=b && a<=c);}  
     58 inline int acc(int a,int b)                    {RT !!(a & (1<<b-1));}  
     59 inline int fil(int a,int b,int c)    {RT a & ~(1<<b-1) | (1<<b-1)*c;}  
     60   
     61 int N, M, K, Q, R, C; 
     62 
     63 int a[20][20];
     64 int f[20][20];//f[i][j]表示 已经选择i列 上一列是j
     65 int sum[20], d[20], csum[20][20];
     66 /*========================================================*/
     67 int main()
     68 {  
     69     #ifndef Generator  
     70     #ifndef ONLINE_JUDGE  
     71     #endif  
     72     #endif                                                         //
     73     #ifdef Generator                                               //
     74         freopen("input.txt","w",stdout);                           //
     75         srand((ui)time(NULL));                                     //
     76     #endif                                                         //
     77     int T, o=0;                                                    //
     78     scanf("%d%d%d%d", &N, &M, &R, &C);                             //
     79     FOR(i, 1, N)                                                   //
     80         FOR(j, 1, M)
     81             scanf("%d", &a[i][j]);
     82     int ans=INF;
     83     FOR(i, 1, (1<<N)-1){//枚举哪些行被选入矩阵
     84         int cnt=0;
     85         FOR(j, 1, N)
     86             if (acc(i, j)) d[++cnt]=j;
     87         if (cnt != R) continue;
     88         FOR(j, 1, M){
     89             sum[j]=0;
     90             FOR(k, 1, R-1)
     91                 sum[j] += abs(a[d[k]][j]-a[d[k+1]][j]);
     92         }
     93         FOR(j, 1, M)
     94             FOR(k, j+1, M){
     95                 csum[j][k]=0;
     96                 FOR(l, 1, R)
     97                     csum[j][k] += abs(a[d[l]][j]-a[d[l]][k]);
     98             }
     99         CLR(f, 0x3f);
    100         f[0][0]=0;
    101         FOR(j, 1, C){
    102             FOR(k, 1, M){
    103                 int tot=0;
    104                 FOR(l, 0, k-1)
    105                     MIN(f[j][k], f[j-1][l]+csum[l][k]+sum[k]);
    106             }
    107         }
    108         FOR(j, 1, M)
    109             MIN(ans, f[C][j]);
    110     }
    111     printf("%d
    ", ans);
    112     RT 0;
    113 }
    114 /*===================================================================*/
    我不怕千万人阻挡,只怕自己投降…
  • 相关阅读:
    leetcode刷题 557~
    Unity正交相机智能包围物体(组)方案
    Embedded Browser(ZFBrowser)使用相关问题
    Unity性能优化
    sipp的使用
    Elment清除表单验证,防止报错小技巧
    git常用命令(干货)
    文本单词one-hot编码
    86. 分隔链表 链表
    5638. 吃苹果的最大数目 优先队列
  • 原文地址:https://www.cnblogs.com/geek-007/p/4297592.html
Copyright © 2011-2022 走看看