zoukankan      html  css  js  c++  java
  • 【Ural1519】— Formula1(轮廓线dp)

    传送门

    看这个大佬的博客吧,讲的很详细:传送门

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    #define ll long long
    #define gc getchar
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    const int M=300005;
    const int N=15;
    int n,m,cnt,idx,mp[N][N],tot[2],bit[N],ex,ey;
    int adj[M],nxt[M],to[M];
    ll f[2][M],sta[2][M],ans;
    char s[N];
    inline void calc(ll s,ll num){
    	int u=s%M;
    	for(int e=adj[u];e;e=nxt[e]){
    		if(sta[idx][to[e]]==s){
    			f[idx][to[e]]+=num;return;
    		}
    	}
    	++tot[idx];
    	sta[idx][tot[idx]]=s;
    	f[idx][tot[idx]]=num;
    	nxt[++cnt]=adj[u];
    	adj[u]=cnt,to[cnt]=tot[idx];
    }
    int main(){
    	for(int i=0;i<N;i++)bit[i]=i<<1;
    	tot[idx]=1,f[idx][1]=1;
    	n=read(),m=read();
    	for(int i=1;i<=n;i++){
    		scanf("%s",s+1);
    		for(int j=1;j<=m;j++){
    			mp[i][j]=(s[j]=='.');
    			if(s[j]=='.')ex=i,ey=j;
    		}
    	}
    	for(int i=1;i<=n;i++){
    		for(int k=1;k<=tot[idx];k++)sta[idx][k]<<=2;
    		for(int j=1;j<=m;j++){
    			memset(adj,0,sizeof(adj));
    			cnt=0,idx^=1;
    			tot[idx]=0;
    			for(int k=1;k<=tot[idx^1];k++){
    				ll s=sta[idx^1][k];
    				ll num=f[idx^1][k];
    				int p=(s>>bit[j-1])%4;
    				int q=(s>>bit[j])%4;
    				if(!mp[i][j]){
    					if(p+q==0)calc(s,num);
    				}
    				else if(p+q==0){
    					if(!mp[i+1][j]||!mp[i][j+1])continue;
    					s=s+(1<<bit[j-1])+2*(1<<bit[j]);
    					calc(s,num);
    				}
    				else if(!p&&q){
    					if(mp[i][j+1])calc(s,num);
    					if(mp[i+1][j]){
    						s=s+q*(1<<bit[j-1])-q*(1<<bit[j]);
    						calc(s,num);
    					}
    				}
    				else if(p&&!q){
    					if(mp[i+1][j])calc(s,num);
    					if(mp[i][j+1]){
    						s=s-p*(1<<bit[j-1])+p*(1<<bit[j]);
    						calc(s,num);
    					}
    				}
    				else if(p+q==2){
    					int b=1;
    					for(int t=j+1;t<=m;t++){
    						int v=(s>>bit[t])%4;
    						if(v==1)b++;
    						if(v==2)b--;
    						if(!b){
    							s=s-(1<<bit[t]);
    							break;
    						}
    					}
    					s=s-(1<<bit[j-1])-(1<<bit[j]);
    					calc(s,num);
    				}
    				else if(p+q==4){
    					int b=1;
    					for(int t=j-2;t;t--){
    						int v=(s>>bit[t])%4;
    						if(v==2)b++;
    						if(v==1)b--;
    						if(!b){
    							s=s+(1<<bit[t]);
    							break;
    						}
    					}
    					s=s-2*(1<<bit[j-1])-2*(1<<bit[j]);
    					calc(s,num);
    				}
    				else if(p==1&&q==2){
    					if(i==ex&&j==ey)ans+=num;
    				}
    				else if(p==2&&q==1){
    					s=s-2*(1<<bit[j-1])-(1<<bit[j]);
    					calc(s,num);
    				}
    			}
    		}
    	}
    	cout<<ans;
    }
    
  • 相关阅读:
    「Poetize10」封印一击
    「Poetize10」能量获取
    vijosP1499炸毁燃料库
    BZOJ3550: [ONTAK2010]Vacation
    总结#3--一类最小割问题
    BZOJ1976: [BeiJing2010组队]能量魔方 Cube
    BZOJ2132: 圈地计划
    BZOJ2127: happiness
    BZOJ1754: [Usaco2005 qua]Bull Math
    920. 会议室
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145574.html
Copyright © 2011-2022 走看看