• CodeForces 1102F. Elongated Matrix 状压Dp


    传送门

    题意

    给你一个 (n imes m(nleq 16)) 的矩阵,你可以调整行的顺序,然后一列一列、从上到下依次对每个元素编号
    (kleq |s_i-s_{i+1}|),要求 (k) 的最大值。

    思路

    首先预处理一下任意两行对应位置元素之差绝对值的最大值,
    还有第一行和最后一行这种特殊位置的绝对值之差的最大值
    然后发现暴力全排列会超时
    因为 (n) 很小所以可以状压,
    我设 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;
    }
    
  • 相关阅读:
    SAP中的文档维护
    SAP日期处理函数汇总(转)
    PR PO通过fm创建时,如何传输增强字段
    html+jQuery简单的利息计算器
    上传项目到github
    Nodejs-毕业设计5-小技巧
    Nodejs-毕业设计4-登录页面
    Nodejs-毕业设计3-路径
    Nodejs-毕业设计2-下载依赖准备工作
    Nodejs-毕业设计1-部署环境
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12164534.html
Copyright © 2020-2023  润新知