Plug DP second question, debug for one night, so today's Mid-Autumn Festival did not see the moon, but finally got it done, thinking habits wrong thing, find for a long time, the idea is actually similar to the preceding contour scanning, but we need to merge the last two plugs in the last one to ensure that there is only one loop. This task cannot be completed simply by the binary scanning method, so we need to use the brackets notation, the cqd PPT is very clear. I don't want to explain it. It should be represented in three hexadecimal notation. We use two binary operators to represent three hexadecimal notation. In this way, there are two ^ (26) states, too many, even if space permits, the time cannot pass, so hash is required. Here I refer to the hash method of the question template of small HH. This method can be promoted to many places, however, I used to use queue to subtract the state, but later I changed it to set because of insufficient space. Now I have learned this hash method.
ID |
Date |
Author |
Problem |
Language |
Judgement result |
Test # |
Execution time |
Memory Used |
4481783 |
21:55:33 30 Sep 2012 |
Xym |
1519. Formula 1 |
C ++ |
Accepted |
|
0.125 |
1 236 KB |
#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<algorithm>#include<cmath>#include<map>#include<queue>#define LL long longusing namespace std;const int maxn=30001;int n,m;int mov[13]={0,2,4,6,8,10,12,14,16,18,20,22,24};char gp[20][20],fx,fy;inline LL getbit(LL st,int k){return (st>>mov[k])&3; }inline LL pybit(LL st,int k){return st<<mov[k];}inline LL clrbit(LL st,int k){ return st&(~(3<<mov[k]));}inline LL clrbit(LL st,int i,int j){ return st&(~(3<<mov[i]))&(~(3<<mov[j]));}inline LL clrbit(LL st,int i,int j,int k){ return st&(~(3<<mov[i]))&(~(3<<mov[j]))&(~(3<<mov[k]));}struct node{int head[maxn],next[maxn],size;LL sum[maxn],sta[maxn];void clear(){memset(head,-1,sizeof(head));memset(sum,0,sizeof(sum));size=0;}void push(LL st,const LL v){LL hash=st%maxn;for(int i=head[hash];i>=0;i=next[i]){if(sta[i]==st){sum[i]+=v;return;}}sta[size]=st,sum[size]=v;next[size]=head[hash],head[hash]=size++;}}dp[2];int fl(int st,int pos){int cnt=1;for(int i=pos+1;i<=m;i++){int k=((st>>mov[i])&3);if(k==1)cnt++;else if(k==2)cnt--;if(!cnt)return i;}}int fr(int st,int pos){int cnt=1;for(int i=pos-1;i>=0;i--){int k=((st>>mov[i])&3);if(k==2)cnt++;else if(k==1)cnt--;if(!cnt)return i;}}LL DP(){LL ans=0;dp[0].clear();dp[0].push(0,1);int now=0,pre=1;for(int i=1;i<=n;i++){pre=now,now^=1;dp[now].clear();for(int j=0;j<dp[pre].size;j++)dp[now].push(dp[pre].sta[j]<<2,dp[pre].sum[j]);for(int j=1;j<=m;j++){pre=now,now^=1;dp[now].clear();for(int k=0;k<dp[pre].size;k++){LL l=getbit(dp[pre].sta[k],j-1);LL up=getbit(dp[pre].sta[k],j);LL st=clrbit(dp[pre].sta[k],j-1,j);//cout<<i<<' '<<j<<' '<<l<<' '<<up<<' '<<st<<' '<<dp[pre].sta[k]<<' '<<dp[pre].sum[k]<<endl;if(!l&&!up){if(gp[i][j]=='*'){dp[now].push(st,dp[pre].sum[k]);continue;}if(i<n&&j<m&&gp[i+1][j]=='.'&&gp[i][j+1]=='.')dp[now].push(st|pybit(1,j-1)|pybit(2,j),dp[pre].sum[k]);}else if(!l||!up){int e=l==0?up:l;if(i<n&&gp[i+1][j]=='.')dp[now].push(st|pybit(e,j-1),dp[pre].sum[k]);if(j<m&&gp[i][j+1]=='.')dp[now].push(st|pybit(e,j),dp[pre].sum[k]);}else if(l==1&&up==1)dp[now].push(st^pybit(3,fl(st,j)),dp[pre].sum[k]);else if(l==2&&up==2)dp[now].push(st^pybit(3,fr(st,j-1)),dp[pre].sum[k]);else if(l==2&&up==1)dp[now].push(st,dp[pre].sum[k]);else if(i==fx&&j==fy)dp[now].push(st,dp[pre].sum[k]);}}}for(int i=0;i<dp[now].size;i++)if(dp[now].sta[i]==0)return dp[now].sum[i];return 0;}int main(){//freopen("text1.out","w",stdout);while(~scanf("%d%d",&n,&m)){for(int i=1;i<=n;i++)scanf("%s",&gp[i][1]);fx=0;for(int i=n;i>0&&!fx;i--){for(int j=m;j>0&&!fx;j--){if(gp[i][j]=='.')fx=i,fy=j;}}cout<<DP()<<endl;}return 0;}