zoukankan      html  css  js  c++  java
  • ZOJ3213-Beautiful Meadow

    题意

    有一个 (n imes m) 的方格纸,每个格子要么不能走,要么有一个权值。求一条简单路径权值和最大。简单路径是指不相交,不经过同一个格子的一条路经。(n,mle 8)

    分析

    既然是路径,就要用到独立插头。这题的问题在于 起点终点不确定

    不确定起点终点,关系到两种情况的处理。第一种是当前转移格子没有左插头和上插头。

    plug

    格子可以不走,所以可以直接转移到 (a=b=0) 。也可以新建连通块,(a=1,b=2)

    若当前其他位置上的独立插头个数小于 2 ,那也可以在这里新建一个独立插头,(a=3,b=0)(a=0,b=3)

    对于 (x,y) 中只有一个插头的情况,首先可以正常延伸。有了独立插头,我们还需要考虑 每个插头是否能够变成独立插头 。当左上为单插头,并且当前独立插头个数小于 2 ,那我们可以让这个插头变成独立插头。

    (x=0,y=3)(x=3,y=0) ,这就意味着可能这条路径在这里终止。若除了这个插头就没有其他的插头,那可以在这里更新答案,不转移。(x=y=3) 同理。

    复杂度为 (O(nm|s|))

    代码

    把情况全部拿出来分开讨论,之后再看能不能合并在一起实现,这样不容易出错。

    #include<bits/stdc++.h>
    #include<ext/pb_ds/assoc_container.hpp>
    #include<ext/pb_ds/hash_policy.hpp>
    #define MapType cc_hash_table
    using namespace std;
    using namespace __gnu_pbds;
    inline int read() {
    	int x=0,f=1;
    	char c=getchar();
    	for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    	for (;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    typedef MapType<int,int> Map;
    typedef MapType<int,int*> Mat;
    typedef Map::iterator itt;
    const int maxn=10;
    int n,m,a[maxn][maxn],fx,fy;
    Map f,g;
    Mat mat;
    template<typename T> inline void Max(T &x,T y) {x=max(x,y);}
    inline int get(int x,int p) {return (x>>(p<<1))&3;}
    inline int mod(int x,int p,int d) {return (x&(~(3<<(p<<1))))+(d<<(p<<1));}
    inline void match(int x,int *&mt) {
    	mt=new int[maxn];
    	static int sta[maxn],top;
    	top=0;
    	for (int i=1;i<=m+1;++i) {
    		const int d=get(x,i);
    		if (d==1) sta[++top]=i; else if (d==2) {
    			int y=sta[top--];
    			mt[y]=i,mt[i]=y;
    		}
    	}
    }
    inline int& F(int x) {
    	if (mat.find(x)==mat.end()) match(x,mat[x]);
    	return f[x];
    }
    void dec(int x) {
    	for (int j=0;j<=m+1;++j) printf("%d %c",((x>>(j<<1))&3)," 
    "[j==m+1]);
    	for (int j=0;j<=m+1;++j) printf("%d %c",j," 
    "[j==m+1]);
    }
    void work() {
    	f.clear(),g.clear();
    	for (Mat::iterator it=mat.begin();it!=mat.end();++it) {
    		delete [] it->second;
    		it->second=NULL;
    	}
    	mat.clear();
    	n=read(),m=read();
    	int ans=0;
    	for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) Max(ans,a[i][j]=read());
    	for (int i=n;i;--i) for (int j=m;j;--j) if (a[i][j]) {
    		fx=i,fy=j;
    		goto zwl;
    	}
    	zwl:F(0)=0;
    	for (int i=1;i<=n;++i) {
    		f.swap(g),f.clear();
    		for (itt it=g.begin();it!=g.end();++it) {
    			const int &d=it->first,&w=it->second,s=get(d,0);
    			if (get(d,m+1)==0) F(((d^s)<<2)|s)=w;
    		}
    		for (int j=1;j<=m;++j) {
    			f.swap(g),f.clear();
    			for (itt it=g.begin();it!=g.end();++it) {
    				const int &d=it->first,&w=it->second,s=get(d,0),e=mod(mod(d,j,0),j+1,0);
    				const int x=get(d,j),y=get(d,j+1),&aij=a[i][j],*mt=mat[d];
    				if (!aij) {
    					if (x==0 && y==0) Max(F(d),w);
    					continue;
    				} 
    				if (x==0 && y==0) {
    					Max(F(d),w);
    					Max(F(mod(mod(d,j,1),j+1,2)),w+aij);
    					if (s>=2) continue;
    					int v=mod(d,0,s+1);
    					Max(F(mod(mod(v,j,3),j+1,0)),w+aij);
    					Max(F(mod(mod(v,j,0),j+1,3)),w+aij);
    				} else if (x==0 || y==0) {
    					Max(F(mod(e,j,x+y)),w+aij);
    					Max(F(mod(e,j+1,x+y)),w+aij);
    					if (x+y==3) {
    						if (e<4) Max(ans,w+aij);
    					} else Max(F(mod(e,mt[j+(x==0)],3)),w+aij);
    				} else if (x==1 && y==1) Max(F(mod(e,mt[j+1],1)),w+aij); 
    				else if (x==1 && y==3) Max(F(mod(e,mt[j],3)),w+aij); 
    				else if (x==2 && y==1) Max(F(e),w+aij); 
    				else if (x==2 && y>1) Max(F(mod(e,mt[j],y)),w+aij); 
    				else if (x==3 && (y==1 || y==2)) Max(F(mod(e,mt[j+1],3)),w+aij); 
    				else if (x==3 && y==3 && e<4) Max(ans,w+aij); 
    			}
    		}
    	}
    	Max(ans,f[0]);
    	printf("%d
    ",ans);
    }
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("test.in","r",stdin);
    #endif
    	int T=read();
    	while (T--) work();
    	return 0;
    }
    
  • 相关阅读:
    LeetCode(111) Minimum Depth of Binary Tree
    LeetCode(108) Convert Sorted Array to Binary Search Tree
    LeetCode(106) Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode(105) Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode(99) Recover Binary Search Tree
    【Android】通过经纬度查询城市信息
    【Android】自定义View
    【OpenStack Cinder】Cinder安装时遇到的一些坑
    【积淀】半夜突然有点想法
    【Android】 HttpClient 发送REST请求
  • 原文地址:https://www.cnblogs.com/owenyu/p/7518855.html
Copyright © 2011-2022 走看看