• 2014NOIP普及组 子矩阵


    觉得题目水的离开
    觉得普及组垃圾的请离开
    不知道 DFS 和 DP 的请离开
    不屑的大佬请离开
    …….
    感谢您贡献的访问量

    ————————————————华丽的分割线 ————————————————

    先看题面:

    题目描述
    给出如下定义:
    子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵。
    例如,下面左图中选取第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列的子矩阵,使得这个子矩阵的分值最小,并输出这个分值。
    输入输出格式
    输入格式:
    第一行包含用空格隔开的四个整数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。


    思路:

    对于50%的数据,太小了直接DFS强行求解就可以啦,然而优秀的oier显然不屑于这50分,我们要打正解。对于100%的数据1 ≤ n ≤ 16,1 ≤ m ≤ 16,DFS显然不能裸跑AC(尤其是在NOIP评测机上),直接DP也不怎么好写,所以正解就是DFS + DP。只要DFS选哪一行 O(2 ^ n),再加一个DP O(n^3)求选了这些行的最小子矩阵的值即可。
    用f[i][j]表示选了i列,最后一列为j的最小子矩阵的值,w[i]表示第i列,行与行之间的绝对值和,v[i][j]表示第i列到第j列的列与列之间的绝对值和,然后DP即可。

    看代码

    # include <stdio.h>
    # include <stdlib.h>
    # include <string.h>
    # include <iostream>
    # include <math.h>
    using namespace std;
    
    # define mem(a, b) memset(a, b, sizeof(a))
    # define N 20
    # define RG register
    # define IL inline
    # define ll long long
    # define oo 2147483647
    # define max(a, b) ((a) > (b)) ? (a) : (b)
    # define min(a, b) ((a) < (b)) ? (a) : (b)
    
    IL int Get(){
        RG char c = '!'; RG int num = 0, z = 1;
        while(c != '-' && (c < '0' || c > '9')) c = getchar();
        if(c == '-') z = -1, c = getchar();
        while(c >= '0' && c <= '9') num = num * 10 + c - '0', c = getchar();
        return num * z;
    }
    
    int n, m, r, c, a[N][N], w[N], ans = oo, x[N], f[N][N], v[N][N];
    
    IL void DP(){
        mem(v, 0); mem(f, 127); mem(w, 0);
        for(RG int i = 1; i <= m; i++)
            for(RG int j = 1; j < r; j++)
                w[i] += abs(a[x[j]][i] - a[x[j + 1]][i]);
        for(RG int i = 1; i <= m; i++)
            for(RG int j = i + 1; j <= m; j++)
                for(RG int k = 1; k <= r; k++)
                    v[i][j] += abs(a[x[k]][i] - a[x[k]][j]);
        f[0][0] = 0;
        for(RG int i = 1; i <= c; i++)
            for(RG int j = i; j <= m; j++)
                for(RG int k = 0; k < j; k++)
                    f[i][j] = min(f[i][j], f[i - 1][k] + w[j] + v[k][j]);
        for(RG int i = c; i <= m; i++)
            ans = min(ans, f[c][i]);
    }
    
    IL void Dfs(RG int t, RG int pre){
        if(t > r){
            DP();
            return;
        }
        for(RG int i = pre + 1; n - i >= r - t; i++){
            x[t] = i;
            Dfs(t + 1, i);
        }
    }
    
    int main(){
        n = Get(); m = Get(); r = Get(); c = Get();
        for(RG int i = 1; i <= n; i++)
            for(RG int j = 1; j <= m; j++)
                a[i][j] = Get();
        Dfs(1, 0);
        printf("%d
    ", ans);
        return 0;   
    }

    本蒟蒻还是初学者,如有写的不好请见谅

  • 相关阅读:
    mysql 无法连接提示 Authentication plugin &#39;caching_sha2_password&#39; cannot be loaded
    探究分析:快速对大量的数据转换为数组
    SQL Server like 字段
    InfluxDB从原理到实战
    Python学习日记(四十) Mysql数据库篇 八
    MySQL数据库基本操作
    ES入门宝典(详细截图版)
    NameNode &amp;&amp; Secondary NameNode工作机制
    MySQL 两张表关联更新(用一个表的数据更新另一个表的数据)
    mysql单个表拆分成多个表
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206427.html
Copyright © 2020-2023  润新知