zoukankan      html  css  js  c++  java
  • URAL Formula 1 ——插头DP

    【题目分析】

        一直听说这是插头DP入门题目。

        难到爆炸。

        写了2h,各种大常数,ural垫底。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define maxn 2000005
    #define u64 unsigned long long
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    int tot,fac[15],can[50005],top=0,hash[maxn],a[12][12],n,m,ex,ey,b[15];
    u64 dp[2][50005];
    char s[15];
    
    //void print(int x){F(j,0,m) printf("%d",(x%fac[j+1])/fac[j]);}
    
    void init()
    {
    	scanf("%d%d",&n,&m);
    	F(i,0,n-1){scanf("%s",s);F(j,0,m-1)a[i][j]=s[j]=='*'?1:0;}
    	F(i,0,n-1)F(j,0,m-1) if (!a[i][j]) ex=i,ey=j;
    //	printf("The end is %d %d
    ",ex,ey);
    	fac[0]=1;F(i,1,14)fac[i]=fac[i-1]*3;tot=fac[m+1]-1;
    //	printf("tot is %d
    ",tot);
    	F(i,0,tot)
    	{
    		int bac=0,flag=1;
    		F(j,0,m)
    		{
    			if ((i%fac[j+1])/fac[j]==1) bac++;
    			else if ((i%fac[j+1])/fac[j]==2) bac--;
    			if (bac<0) {flag=0;break;}
    		}
    		if (flag&&bac==0) can[++top]=i,hash[i]=top;
    	}
    //	printf("All can is %d
    ",top);
    //	F(i,1,top) {printf("%d is can ",can[i]);print(can[i]);printf("
    ");}
    }
    
    void recode(int x)
    {F(i,0,m)b[i]=(x%fac[i+1])/fac[i];}
    
    int encode()
    {
    	int ret=0;
    	F(i,0,m) ret+=b[i]*fac[i];
    	return ret;
    }
    
    int main()
    {
    	init();
    	int now=1,pre=0;
    	memset(dp[now],0,sizeof dp[now]);
    	dp[now][1]=1;
    	F(i,0,n-1)
    	F(j,0,m-1)
    	{
    		now^=1;pre^=1;
    		memset(dp[now],0,sizeof dp[now]);
    		if (a[i][j])
    		{
    			F(s,1,top) if (dp[pre][s])
    			{
    //				print(can[s]);
    				int tmp1=(can[s]%fac[j+1])/fac[j],tmp2=(can[s]%fac[j+2])/fac[j+1];
    				if (!tmp1&&!tmp2)
    				{
    					dp[now][s]+=dp[pre][s];
    //					printf(" to %d ",s); print(can[s]); printf("
    ");
    				}
    			}
    		}
    		else
    		{
    			F(s,1,top) if (dp[pre][s])
    			{
    //				print(can[s]); printf("
    ");
    				int tmp1=(can[s]%fac[j+1])/fac[j],tmp2=(can[s]%fac[j+2])/fac[j+1],tmp=can[s];
    				if (!tmp1&&!tmp2)
    				{
    					tmp+=1*fac[j];
    					tmp+=2*fac[j+1];
    					dp[now][hash[tmp]]+=dp[pre][s];
    //					printf(" to %d ",hash[tmp]); print(tmp); printf("
    ");
    				}
    				else if (!tmp1)
    				{
    					dp[now][hash[tmp]]+=dp[pre][s];
    //					printf(" to %d ",hash[tmp]); print(tmp); printf("
    ");
    					tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
    					tmp+=tmp2*fac[j];
    					dp[now][hash[tmp]]+=dp[pre][s];
    //					printf(" to %d ",hash[tmp]); print(tmp); printf("
    ");
    				}
    				else if (!tmp2)
    				{
    					dp[now][hash[tmp]]+=dp[pre][s];
    //					printf(" to %d ",hash[tmp]); print(tmp); printf("
    ");
    					tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
    					tmp+=tmp1*fac[j+1];
    					dp[now][hash[tmp]]+=dp[pre][s];
    //					printf(" to %d ",hash[tmp]); print(tmp); printf("
    ");
    				}
    				else if (tmp1==2&&tmp2==2)
    				{
    					recode(tmp);
    					int pos=0,bac=0;
    					D(z,j-1,0)
    					{
    						if (b[z]==2) bac++;
    						if (b[z]==1) bac--;
    						if (b[z]==1&&bac==-1) {pos=z;break;}
    					}
    					b[j]=b[j+1]=0;
    					b[pos]=2;
    					tmp=encode();
    					dp[now][hash[tmp]]+=dp[pre][s];
    //					printf(" to %d ",hash[tmp]); print(tmp); printf("
    ");
    				}
    				else if (tmp1==1&&tmp2==1)
    				{
    					recode(tmp);
    					int pos=0,bac=0;
    					F(z,j+2,n)
    					{
    						if (b[z]==1) bac++;
    						if (b[z]==2) bac--;
    						if (b[z]==2&&bac==-1) {pos=z;break;}
    					}
    					b[j]=b[j+1]=0;
    					b[pos]=1;
    					tmp=encode();
    					dp[now][hash[tmp]]+=dp[pre][s];
    //					printf(" to %d ",hash[tmp]); print(tmp); printf("
    ");
    				}
    				else if (tmp1==2&&tmp2==1)
    				{
    					tmp-=tmp1*fac[j];
    					tmp-=tmp2*fac[j+1];
    					dp[now][hash[tmp]]+=dp[pre][s];
    //					printf(" to %d ",hash[tmp]); print(tmp); printf("
    ");
    				}
    				else if (tmp1==1&&tmp2==2&&i==ex&&j==ey)
    				{
    					tmp-=tmp1*fac[j];
    					tmp-=tmp2*fac[j+1];
    					dp[now][hash[tmp]]+=dp[pre][s];
    //					printf(" to %d ",hash[tmp]); print(tmp); printf("
    ");
    				}
    			}
    		}
    		if (j==m-1)
    		{
    			now^=1; pre^=1;
    			memset(dp[now],0,sizeof dp[now]);
    			F(s,1,top) if (dp[pre][s])
    			{
    //				print(can[s]);
    				recode(can[s]);
    				if (b[m]!=0)
    				{
    //					printf(" can't
    ");
    					continue;
    				}
    				D(i,m,1) b[i]=b[i-1];
    				b[1]=0;
    				int tmp=encode();
    				if (!hash[tmp]) {continue;}
    				dp[now][hash[tmp]]+=dp[pre][s];
    //				printf(" rev to %d ",hash[tmp]); print(tmp); printf("
    ");
    			}
    		}
    //		printf("
    ");
    	}
    	printf("%llu
    ",dp[now][1]);
    }
    

      

  • 相关阅读:
    jsp自定义标签
    spring JDBC 返回list<map>集合
    AWS 身份及验证服务(四)
    AWS 存储服务(三)
    AWS 核心服务概述(二)
    云计算和 AWS 概述(一)
    AWS 解决方案架构师考点(Storage)
    利用 AWS 无服务架构之语音合成
    AWS 云上安全最佳实践
    持续集成 Jenkins +Gitlab + SSH 自动发布 HTML 代码
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6435430.html
Copyright © 2011-2022 走看看