zoukankan      html  css  js  c++  java
  • 【ZOJ3256】Tour in the Castle (插头dp)

    Tour in the Castle

    题意

    After the final BOSS is defeated, the hero found that the whole castle is collapsing (very familiar scene, isn't it). Escape from the castle is easy, just need to cross a few rooms. But as the Hero is full of adventurous spirit, he decides to visit every room before he escape the castle.

    The castle is a rectangle with N * M rooms in it. Two rooms are connected if they share a common edge. The hero starts in the top left room. And the bottom left room is the only way out. After the hero visits a room and leaves it, it will collapse immediately(Another familiar scene). So he can visit each room only once.

    The diagram shows one tour over a castle with 4 * 10 rooms:

    思路

    看m的范围,可以用矩阵加速

    原来是逐格递推,现在要改成逐行递推。

    考虑合法状态,因为平常记录的是括号序列,所以枚举状态的时候判断是否是合法的括号序列并直接枚举算之后的转移状态。

    转移的时候要注意如果此时没有插头一定是无法继续向下转移的,或者上面已经形成回路后也不能向下转移。

    //ZOJ 3256
    #include<bits/stdc++.h>
    using namespace std;
    const int Mod=7777777;
    int id=0,a[8],pos[17005],Id[135],n,m,b[8],inv[8];
    void Put(int x) {
    	if(x>=10)Put(x/10);
    	putchar(x%10+'0');
    }
    void Print(int x) {
    	Put(x),puts("");
    }
    int get(int *A) {
    	int now=0;
    	for(int i=n; i>=1; i--)now=now*4+A[i];
    	return now;
    }
    void Printf(int x) {
    	for(int i=1; i<=n; i++)printf("%d",x%4),x>>=2;
    	puts("");
    }
    void add(int &x,int y) {
    	x+=y;
    	if(x>=Mod)x-=Mod;
    	if(x<0)x+=Mod;
    }
    struct node {
    	int A[135][135];
    	void clear() {
    		memset(A,0,sizeof(A));
    	}
    	void Init() {
    		for(int i=0; i<id; i++)for(int j=0; j<id; j++)A[i][j]=(i==j);
    	}
    	node operator*(const node&_)const {
    		node res;
    		res.clear();
    		for(int i=0; i<id; i++)
    			for(int j=0; j<id; j++)
    				for(int k=0; k<id; k++)
    					add(res.A[i][k],1ll*A[i][j]*_.A[j][k]%Mod);
    		return res;
    	}
    } T,B;
    node mul(node A,int y) {
    	node res;
    	res.Init();
    	while(y) {
    		if(y&1)res=res*A;
    		A=A*A,y>>=1;
    	}
    	return res;
    }
    void dfs(int x,int la) {
    	if(x==n+1) {
    		if(la)return;
    		pos[get(a)]=id,Id[id++]=get(a);
    		return;
    	}
    	if(la)a[x]=2,dfs(x+1,la-1);
    	a[x]=1,dfs(x+1,la+1),a[x]=0,dfs(x+1,la);
    }
    void redfs(int x,int now,int rt) {
    	if(x==n+1) {
    		add(T.A[rt][pos[now]],1);
    		return;
    	}
    	int b1=(now>>(2*(x-1)))%4,b2=(now>>(2*x))%4;
    	if(!(b1|b2)) {
    		if(x!=n)redfs(x+1,now+inv[x-1]+2*inv[x],rt);
    	} else if(b1&&!b2) {
    		if(x!=n)redfs(x+1,now-b1*inv[x-1]+b1*inv[x],rt);
    		redfs(x+1,now,rt);
    	} else if(b2&&!b1) {
    		if(x!=n)redfs(x+1,now,rt);
    		redfs(x+1,now+b2*inv[x-1]-b2*inv[x],rt);
    	} else if(b1==1&&b2==1) {
    		int k1=1;
    		for(int i=x+1; i<=n; i++) {
    			if(((now>>(2*i))%4)==1)k1++;
    			else if(((now>>(2*i))%4)==2)k1--;
    			if(!k1) {
    				redfs(x+1,now-inv[x-1]-inv[x]-inv[i],rt);
    				break;
    			}
    		}
    	} else if(b1==2&&b2==2) {
    		int k1=1;
    		for(int i=x-2; i>=0; i--) {
    			if(((now>>(2*i))%4)==1)k1--;
    			else if(((now>>(2*i))%4)==2)k1++;
    			if(!k1) {
    				redfs(x+1,now-inv[x-1]*2-inv[x]*2+inv[i],rt);
    				break;
    			}
    		}
    	} else if(b1==2&&b2==1)redfs(x+1,now-b1*inv[x-1]-b2*inv[x],rt);
    	else if((x==n)&&(now-inv[x-1]*b1-inv[x]*b2==0))redfs(x+1,now-inv[x-1]*b1-inv[x]*b2,rt);
    }
    void Init() {
    	id=0,dfs(1,0);
    	int res=(1<<(2*n+2))-1;
    	for(int i=0; i<id; i++) {
    		if(!Id[i])continue;
    		redfs(1,(Id[i]<<2)&res,i);
    	}
    }
    int main() {
    	inv[0]=1;
    	for(int i=1; i<=7; i++)inv[i]=inv[i-1]<<2;
    	while(~scanf("%d%d",&n,&m)) {
    		T.clear(),Init();
    		T=mul(T,m);
    		int p=inv[0]+2*inv[n-1];
    		p=pos[p],B.clear(),B.A[0][p]=1,B=B*T;
    		if(B.A[0][pos[0]]==0)puts("Impossible");
    		else printf("%d
    ",B.A[0][pos[0]]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    一:理解ASP.NET的运行机制(例:通过HttpModule来计算页面执行时间)
    解决Silverlight F5刷新问题
    C# 将 HTML 转换为图片或 PDF
    C# 使用 Windows API 发送文件到打印机
    C# 各种导入 Excel 文件的数据的方法总结
    C# 使用 SqlBulkCopy 类批量复制数据到数据库
    C# 导出 Excel 的各种方法总结
    C# 使用windows服务发送邮件
    C# 创建、部署和调用WebService的简单示例
    SQL Server 常用函数使用方法(持续更新)
  • 原文地址:https://www.cnblogs.com/cly1231/p/13043801.html
Copyright © 2011-2022 走看看