Elongated Matrix

传送门

题目:

You are given a matrix aa, consisting of nn rows and mm columns. Each cell contains an integer in it.

You can change the order of rows arbitrarily (including leaving the initial order), but you can't change the order of cells in a row. After you pick some order of rows, you traverse the whole matrix the following way: firstly visit all cells of the first column from the top row to the bottom one, then the same for the second column and so on. During the traversal you write down the sequence of the numbers on the cells in the same order you visited them. Let that sequence be s1,s2,…,snms1,s2,…,snm.

The traversal is kk-acceptable if for all ii (1≤i≤nm−11≤i≤nm−1) |si−si+1|≥k|si−si+1|≥k.

Find the maximum integer kk such that there exists some order of rows of matrix aathat it produces a kk-acceptable traversal.

Input

The first line contains two integers nn and mm (1≤n≤161≤n≤16, 1≤m≤1041≤m≤104, 2≤nm2≤nm) — the number of rows and the number of columns, respectively.

Each of the next nn lines contains mm integers (1≤ai,j≤1091≤ai,j≤109) — the description of the matrix.

Output

Print a single integer kk — the maximum number such that there exists some order of rows of matrix aa that it produces an kk-acceptable traversal.

Examples

Input

4 2
9 9
10 8
5 3
4 3

Output

5

Input

2 4
1 2 3 4
10 3 7 3

Output

0

Input

6 1
3
6
2
5
1
4

Output

3

Note

In the first example you can rearrange rows as following to get the 55-acceptable traversal:

5 3
10 8
4 3
9 9

Then the sequence ss will be [5,10,4,9,3,8,3,9][5,10,4,9,3,8,3,9]. Each pair of neighbouring elements have at least k=5k=5 difference between them.

In the second example the maximum k=0k=0, any order is 00-acceptable.

In the third example the given order is already 33-acceptable, you can leave it as it is.

题目大意:给你n行m列的矩阵,有一种遍历顺序,从第第一列第一行开始按列遍历,按遍历顺序得到一个顺序,让你通过一行改变到另一行,使得相邻俩个值差的绝对值的最小值最大;

思路:通过一行一行的改变,那改变之后相邻俩行之间差值的最小值不会发生改变,可以预处理出来,然后对于每一行末尾和下一行开始也可以通过预处理记录,那问题就转换成了将行看成一个整体,对行排列得到目标答案,行的列数位n<=16,然后就是状压,每一位对应相应位置的行,对其状态进形枚举,枚举当前状态的下一行,得到答案;

ac代码:

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<string.h>
#include<stdio.h>
#include<limits.h>
using namespace std;
#define ll long long;
#define swap(a,b){int c=a;a=b;b=c;}
const int maxn=1e4+5;
const int inf=0x3f3f3f3f;
const int mod=10007;
int dp[1<<17][20][20];
int va[20][maxn];
int va1[20][20],va2[20][20];
int n,m;
int dfs(int k,int i,int j){//k为当前状态,i为枚举第一行对应的行,j为当前状态的前一行;
    if(k==(1<<n)-1){//行已经枚举完了,返回不同列之间的差值;
        return va1[j][i];
    }
    if(dp[k][i][j]!=-1)
        return dp[k][i][j];//当前状态已被枚举,直接返回;
    int ans=0;
    for(int a=1;a<=n;a++){
        int k1=1<<(a-1);
        if(k1&k)
            continue;
        ans=max(ans,min(dfs(k|k1,i,a),va2[a][j]));//合法状态,枚举下一行;
    }
    return dp[k][i][j]=ans;
}
int main( ){

    scanf("%d %d",&n,&m);
    for(int a=1;a<=n;a++){
        for(int b=1;b<=m;b++){
            scanf("%d",&va[a][b]);
        }
    }
    for(int a=1;a<=n;a++){
        for(int b=1;b<=n;b++){
            int minn=inf;
            for(int c=1;c<m;c++){
                minn=min(minn,abs(va[a][c]-va[b][c+1]));
            }
            va1[a][b]=minn;
            minn=inf;
            for(int c=1;c<=m;c++){
                minn=min(minn,abs(va[a][c]-va[b][c]));
            }
            va2[a][b]=minn;
        }
    }//预处理;
    memset(dp,-1,sizeof(dp));
    int ans=0;
    for(int a=1;a<=n;a++){
        int k=1<<(a-1);
        ans=max(ans,dfs(k,a,a));
    }//枚举第一行;
    printf("%d\n",ans);
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值