CodeForces 1102F。細長いマトリックス状压Dpは

ポータル

問題の意味

あなたが与える\(N \回M(nは \当量16)\) 行列、あなたが行の順序、および1つを調整することができ、各要素の上から下に番号が付けられ
\(K \当量| s_i- + {I} 1 S_ |。\) 必要\(K \)最大。

思考

最初は、任意の2つのラインの間の差の絶対値の最大要素に対応する位置に、前処理、
ならびに最大値との差の絶対値のこの特定の位置の最初と最後の行
と暴力の全体構成は、タイムアウトを発見した
ので\(N- \ )非常に小さな圧力は、成形することができる
最大最小差分絶対値IセットF [17] [17] [ 200000]を最初の行の数を満たすために、現在選択された行の数、選択された数の選択されました実際には、最初の行番号を覚えておくことは行くことができません
そして、あなたは、検索メモリを実行することができ、ダイナミックなリターンを書くのはあまりにもハード

コード

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int MAXN=1e4+10;
int n,m,mt[20][MAXN];
int as[20][20],bs[20][20],ans;
int f[17][17][200000];

inline int dfs(int pos,int first,int last,int stu){
    if(pos==n+1){
        return bs[first][last];
    }
    if(f[first][last][stu]!=-1) return f[first][last][stu];
    for(int i=1;i<=n;i++){
        if((stu&(1<<i))==0){
            f[first][last][stu]=max(f[first][last][stu],min(dfs(pos+1,first,i,stu|(1<<i)),as[i][last]));
        }
    }
    return f[first][last][stu];
}

int main(){
//  freopen("data.in","r",stdin);
//  freopen("data.out","w",stdout);
    memset(as,0x3f,sizeof(as));
    memset(bs,0x3f,sizeof(bs));
    memset(f,-1,sizeof(f));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            scanf("%d",&mt[i][j]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=m;k++){
                as[i][j]=min(as[i][j],abs(mt[i][k]-mt[j][k]));
                if(k<m) bs[i][j]=min(bs[i][j],abs(mt[i][k+1]-mt[j][k]));
            }
    for(int i=1;i<=n;i++)
        ans=max(ans,dfs(2,i,i,1<<i));
    cout<<ans<<endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/BakaCirno/p/12164534.html