zoukankan      html  css  js  c++  java
  • hdu3377-Plan

    题意

    一个 (n imes m) 的矩阵中每个位置有一个整数,求一条路径从 ((1,1)) 走到 ((n,m)) ,每个点不能重复经过,求最大权值和。(1le nle 8,1le mle 9,|w|le 2000)

    分析

    不再是回路了!一条路径!

    两种想法。第一种,把它变成一个回路。这就有了第一种做法,在整个矩阵左边补两列,下面补两行,构造一个必须经过到通道,求回路。这样就把这个问题转化成了之前到哈密顿回路问题,插头dp最小权值即可。

    第二种想法,改进之前到插头dp,使之能够处理路径问题。我们发现,起点和终点不再能够接受一个连通块了,它只接受一条单独到路径。因此我们引入独立插头。所谓独立插头,就是一个单独的插头,不与其他任何一个插头相连,用第四个数字 3 来表示(终于集齐真正的四进制了!)

    一样的讨论一下就好啦。

    有一些要注意的地方。有一些情况是不存在的,比如 ((x,y)=(3,3),(1,2),(1,3),(3,2))

    在dp的时候,((1,1))((n,m)) 只能接受单独的独立插头,对这两种情况特判一下。特判的时候记得要 continue

    写的时候还出现了一些问题,比如漏掉了一个位置可以为空的情况,加回去后又不小心加了当前点的权值。还有这题需要特判一下 (n=m=1) 的情况,因为我的写法是先判断 ((n,m)) 再判 ((1,1)) 的。

    没有手写哈希,用了 unordered_map ,代码十分好写,只不过用时是zwl的两倍。

    hdu的g++升级了,自带 C++ 11 的支持!!

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=11;
    const int maxs=2e4;
    typedef unordered_map<int,int> Map;
    int a[maxn][maxn],n,m,mat[maxs][maxn],ids,cas=0;
    Map f,g,id;
    inline void Max(int &x,int y) {x=max(x,y);}
    void match(int mt[],int x) {
    	static int sta[maxn],b[maxn];
    	int top=0;
    	for (int i=1;i<=m+1;++i) b[i]=((x>>=2)&3);
    	for (int i=1;i<=m+1;++i) if (b[i]==1) sta[++top]=i; else if (b[i]==2) {
    		int x=sta[top--];
    		mt[x]=i,mt[i]=x;
    	} else mt[i]=0;
    }
    inline int& F(int x) {
    	if (!id[x]) match(mat[id[x]=++ids],x);
    	Map::iterator it=f.find(x);
    	if (it==f.end()) f[x]=INT_MIN;
    	return f[x];
    }
    inline int get(int d,int p) {
    	return (d>>(p<<1))&3;
    }
    inline int mod(int d,int p,int x) {
    	return (d&(~(3<<(p<<1))))+(x<<(p<<1));
    }
    vector<int> dec(int x) {
    	vector<int> ret;
    	ret.clear();
    	for (int i=1;i<=m+1;++i) ret.push_back((x>>=2)&3);
    	return ret;
    }
    static void print(int x) {
    	static int cas=0;
    	printf("Case %d: %d
    ",++cas,x);
    }
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("test.in","r",stdin);
    #endif
    	while (~scanf("%d%d",&n,&m)) {
    		for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) scanf("%d",&a[i][j]);
    		if (n==1 && m==1) {
    			print(a[1][1]);
    			continue;
    		}
    		f.clear(),g.clear(),id.clear(),ids=0;
    		F(0)=0;
    		for (int i=1;i<=n;++i) {
    			f.swap(g),f.clear();
    			for (Map::iterator it=g.begin();it!=g.end();++it) {
    				const int &d=it->first,&w=it->second;
    				if (get(d,m+1)==0) F(d<<2)=w;
    			}
    			for (int j=1;j<=m;++j) {
    				f.swap(g),f.clear();
    				for (Map::iterator it=g.begin();it!=g.end();++it) {
    					const int &d=it->first,&w=it->second;
    					int x=get(d,j),y=get(d,j+1);
    					if (i==n && j==m) {
    						if (x==3 && mod(d,j,0)==0) Max(F(0),w+a[i][j]);
    						if (y==3 && mod(d,j+1,0)==0) Max(F(0),w+a[i][j]);
    						continue;
    					}
    					if (x==0 && y==0) {
    						if (i==1 && j==1) {
    							int v1=mod(d,j,3),v2=mod(d,j+1,3);
    							Max(F(v1),w+a[i][j]),Max(F(v2),w+a[i][j]);
    							continue;
    						} 
    						Max(F(mod(mod(d,j,1),j+1,2)),w+a[i][j]);
    						Max(F(d),w);
    					} else if (x==1 && y==1) {
    						int v=mod(mod(d,j,0),j+1,0);
    						v=mod(v,mat[id[d]][j+1],1);
    						Max(F(v),w+a[i][j]);
    					} else if (x==2 && y==2) {
    						int v=mod(mod(d,j,0),j+1,0);
    						v=mod(v,mat[id[d]][j],2);
    						Max(F(v),w+a[i][j]); 
    					} else if (x==0 || y==0) {
    						int v1=mod(mod(d,j,x+y),j+1,0),v2=mod(mod(d,j,0),j+1,x+y);
    						Max(F(v1),w+a[i][j]),Max(F(v2),w+a[i][j]);
    					} else if (x==2 && y==1) {
    						int v=mod(mod(d,j,0),j+1,0);
    						Max(F(v),w+a[i][j]);
    					} else if (x==2 && y==3) {
    						int v=mod(mod(d,j,0),j+1,0);
    						v=mod(v,mat[id[d]][j],3);
    						Max(F(v),w+a[i][j]);
    					} else if (x==3 && y==1) {
    						int v=mod(mod(d,j,0),j+1,0);
    						v=mod(v,mat[id[d]][j+1],3);
    						Max(F(v),w+a[i][j]);
    					}
    				}
    			}
    		}
    		print(F(0));
    	}
    	return 0;
    }
    
  • 相关阅读:
    前端中不同页面之间传递参数的几种方式
    js中的闭包内存图
    【JavaScript基础】js中关于声明提前的几个误区
    【面试】前端面试题
    js继承的几种方式
    原生Ajax实现异步交互
    git基本使用
    一个简单的SSM框架实例(使用IDEA)
    高安全性的JavaScript
    高性能的JavaScript
  • 原文地址:https://www.cnblogs.com/owenyu/p/7479372.html
Copyright © 2011-2022 走看看