码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #531 (Div. 3) F. Elongated Matrix(状压DP)

时间:2019-01-10 21:54:12      阅读:285      评论:0      收藏:0      [点我收藏+]

标签:col   ons   ==   ted   sdn   代码   article   一个   font   

F. Elongated Matrix

题目链接:https://codeforces.com/contest/1102/problem/F

题意:

给出一个n*m的矩阵,现在可以随意交换任意的两行,最后从上到下,从左到右形成一个序列s1,s2.....snm,满足对于任意相邻的两个数,它们差的绝对值的最大值为k。

现在问怎么交换行与行,可以使得最后的这个k最大。

 

题解:

人生中第一道状压dp~其实还是参考了这篇博客:https://blog.csdn.net/CSDNjiangshan/article/details/86239183?tdsourcetag=s_pctim_aiomsg

这篇博客思路已经说得很清楚了,我就说下注意的几点吧:

行和列的下标是从0开始的,这是为了适应二进制操作,结合代码想想就知道了,我一开始就是这里没注意;

还有就是n=1时的特判,代码不能很好地处理这种情况,这时横坐标是0,不是1....

其余的照着思路写就是了。

我还有一个谜之问题,就是我先枚举中间点,比后枚举中间点要慢200.300ms左右,不知道为什么,希望有大佬能帮我解答一下。

 

代码如下:

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 16 , M = 1e4+5;
int a[N][M];
int dp[N][N][1<<N];
int n,m;
int dis[N][N],dis_next[N][N];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            scanf("%d",&a[i][j]);
    memset(dis,INF,sizeof(dis));
    memset(dis_next,INF,sizeof(dis_next));
    memset(dp,0,sizeof(dp));
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i==j) continue ;
            for(int k=0;k<m;k++) dis[i][j]=min(dis[i][j],abs(a[i][k]-a[j][k]));
            for(int k=0;k<m-1;k++) dis_next[i][j]=min(dis_next[i][j],abs(a[i][k+1]-a[j][k]));
        }
    }
    int ans = 0;
    if(n==1){
        ans = INF;
        for(int i=0;i<m-1;i++) ans=min(ans,abs(a[0][i]-a[0][i+1]));
        printf("%d",ans);
        return 0;
    }
    for(int l=0;l<n;l++) dp[l][l][1<<l]=INF;
    for(int l=1;l<(1<<n);l++){
        for(int i=0;i<n;i++){
            if((l>>i)&1==0) continue ;
            for(int j=0;j<n;j++){
                if((l>>j)&1 || i==j) continue ;
                for(int k=0;k<n;k++){
                    if((l>>j)&1==0) continue ;
                    int now = l|(1<<j);
                    dp[i][j][now]=max(dp[i][j][now],min(dp[i][k][l],dis[k][j]));
                }
            }
        }
    }
    int now = (1<<n)-1;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i==j) continue ;
            ans=max(ans,min(dp[i][j][now],dis_next[i][j]));
        }
    }
    printf("%d",ans);
    return 0;
}

 

Codeforces Round #531 (Div. 3) F. Elongated Matrix(状压DP)

标签:col   ons   ==   ted   sdn   代码   article   一个   font   

原文地址:https://www.cnblogs.com/heyuhhh/p/10252277.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!