Matrices

Los goo

Meaning of the questions: given the following definition:

1. Matrices: Select a new matrix composed of certain rows and certain columns of a matrix from which the intersection position (relative order to maintain row and column) is called a sub-matrix of the original matrix.

2. adjacent elements: an element of the matrix with its up and down around the four elements (if any) are adjacent.

3. score matrix: the matrix and the absolute value of the difference between each of the adjacent element of.

The title task: Given a \ (n-\) OK \ (m \) positive integer matrix column, please select from this matrix a \ (R & lt \) line \ (C \) sub-matrix column, such that this the minimum value of the sub-matrix, and outputs the value.

\(n,m<=16.\)

Analysis: direct violence enumerate the composition of all the lines, followed by \ (the DP \) which columns can be determined such that the minimum value selected from the set. \ (F [i] [J] \) represents the total of the front column i is selected from the j-th column and the selected minimum value of the i-th column, \ (DIS [i] \) represents the value of the i-th column (in the case of what is known line selected), \ (dist [i] [j ] \) represents the i th column and the value j-th column is generated (in the case of what is known selected row), then \ (f [i] [j ] = f [k] [j-1] + dist [ k] [i] + dis [ i]. \)

After completion of each selected row, \ (the DP \) before a column, apparently \ (dis, dist \) two arrays are to be pretreated.

Time complexity should be \ (^ R & lt C_n. 3 * m ^ \) . Anyway able to live.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int N=20;
int n,m,r,c,ans=1e9;
int bj[N],a[N],dis[N];
int jz[N][N],dist[N][N],f[N][N];
inline void dp(){
    memset(dis,0,sizeof(dis));
    memset(dist,0,sizeof(dist));
    memset(f,0x3f,sizeof(f));//初始化
    for(int j=1;j<=m;++j)
        for(int i=1;i<r;++i)
            dis[j]+=abs(jz[a[i]][j]-jz[a[i+1]][j]);
    for(int j=1;j<m;++j)
        for(int k=j+1;k<=m;++k)
            for(int i=1;i<=r;++i)
                dist[j][k]+=abs(jz[a[i]][j]-jz[a[i]][k]);   
    for(int i=1;i<=m;++i)f[i][1]=dis[i];
    for(int i=1;i<=m;++i)
        for(int j=2;j<=min(i,c);++j)
            for(int k=j-1;k<=i-1;++k)
                f[i][j]=min(f[i][j],f[k][j-1]+dist[k][i]+dis[i]);
    for(int i=c;i<=m;++i)ans=min(ans,f[i][c]);
}
inline void dfs(int now){//搜索枚举所有的行的组成情况
    if(now>r){dp();return;}//选完了之后就去dp列的情况
    for(int i=1;i<=n;++i)
        if(!bj[i]&&a[now-1]<i){//保证选出的行是递增的,也算是避免重复搜索状态
            bj[i]=1;
            a[now]=i;
            dfs(now+1);
            bj[i]=0;
        }
}
int main(){
    n=read();m=read();r=read();c=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            jz[i][j]=read();
    dfs(1);printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/PPXppx/p/11617687.html