poj 1739 Tony's Tour

来源:互联网 发布:7日年化收益率简单算法 编辑:程序博客网 时间:2024/06/08 14:50

楼教主的男人八题之一,这是我切的第一题,昨天搞定了括号表示法,今天趁热打铁,这题很容易想到把左下和右下两个格子连起来,构成一条哈密顿回路,就和上一题一样,不过这条路有一条必须经过的路径,我们需要特殊处理,做法有两种,我是添加了一层,然后特殊处理最后一层,后来发现小hh的解法说不用,又写了另一种解法,就是将最后一层的状态变成初始状态,然后从底往上dp,这种写法比较好,简单,而且状态比第一种写法少。

Run IDUserProblemResultMemoryTimeLanguageCode LengthSubmit Time108732392010307204251739Accepted1456K110MSG++2941B2012-10-01 17:28:50108731932010307204251739Accepted1444K125MSG++3493B2012-10-01 17:15:55108730992010307204251739Accepted1456K94MSG++2943B2012-10-01 16:48:33第二种写法

#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<algorithm>#include<cmath>#define LL long longusing namespace std;const int maxn=30001;int n,m,lx,ly,rx,ry,mov[9]={0,2,4,6,8,10,12,14,16};LL getbit(int st,int k){return (st>>mov[k])&3;}LL pybit(int st,int k){return (st<<mov[k]);}LL clrbit(int st,int a,int b){return st&(~(3<<mov[a]))&(~(3<<mov[b]));}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;}}sum[size]=v,sta[size]=st;next[size]=head[hash],head[hash]=size++;}}dp[2];int fl(LL st,int k){int cnt=1;for(int j=k+1;j<=m;j++){int e=getbit(st,j);if(e==2)cnt--;else if(e==1)cnt++;if(cnt==0) return j;}}int fr(LL st,int k){int cnt=1;for(int j=k-1;j>=0;j--){int e=getbit(st,j);if(e==2)cnt++;else if(e==1)cnt--;if(cnt==0) return j;}}char gp[20][20];LL DP(){LL ans=0;dp[0].clear();dp[0].push(pybit(1,0)|pybit(2,m-1),1);int now=0,pre=1;for(int i=n;i>=1;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,jj=m;j<=m;j++,jj--){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<<' '<<jj<<' '<<l<<' '<<up<<' '<<st<<' '<<dp[pre].sta[k]<<' '<<dp[pre].sum[k]<<endl;if(!l&&!up){if(gp[i][jj]=='#')dp[now].push(dp[pre].sta[k],dp[pre].sum[k]);else if(i>1&&jj>1&&gp[i-1][jj]=='.'&&gp[i][jj-1]=='.')dp[now].push(st|pybit(1,j-1)|pybit(2,j),dp[pre].sum[k]);}else if(!l||!up){LL e=l==0?up:l;if(i>1&&gp[i-1][jj]=='.')dp[now].push(st|pybit(e,j-1),dp[pre].sum[k]);if(jj>1&&gp[i][jj-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(lx==i&&ly==jj)dp[now].push(st,dp[pre].sum[k]);}}}for(int i=0;i<dp[now].size;i++)if(dp[now].sta[i]==0)ans+=dp[now].sum[i];return ans;}int main(){while(~scanf("%d%d",&n,&m)){if(n==0&&m==0) break;for(int i=1;i<=n;i++)scanf("%s",&gp[i][1]);lx=ly=0;for(int i=1;i<=n&&!lx;i++){for(int j=1;j<=m&&!lx;j++)if(gp[i][j]=='.')lx=i,ly=j;}//cout<<lx<<' '<<ly<<endl;cout<<DP()<<endl;}return 0;}

第一种写法

#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<algorithm>#include<cmath>#define LL long longusing namespace std;const int maxn=30001;int n,m,lx,ly,rx,ry,mov[9]={0,2,4,6,8,10,12,14,16};LL getbit(int st,int k){return (st>>mov[k])&3;}LL pybit(int st,int k){return (st<<mov[k]);}LL clrbit(int st,int a,int b){return st&(~(3<<mov[a]))&(~(3<<mov[b]));}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;}}sum[size]=v,sta[size]=st;next[size]=head[hash],head[hash]=size++;}}dp[2];int fl(LL st,int k){int cnt=1;for(int j=k+1;j<=m;j++){int e=getbit(st,j);if(e==2)cnt--;else if(e==1)cnt++;if(cnt==0) return j;}}int fr(LL st,int k){int cnt=1;for(int j=k-1;j>=0;j--){int e=getbit(st,j);if(e==2)cnt++;else if(e==1)cnt--;if(cnt==0) return j;}}char gp[20][20];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(dp[pre].sta[k],dp[pre].sum[k]);else if((i<n&&j<m&&gp[i+1][j]=='.'&&gp[i][j+1]=='.')||i==n)dp[now].push(st|pybit(1,j-1)|pybit(2,j),dp[pre].sum[k]);}else if(!l||!up){LL e=l==0?up:l;if((i<n&&gp[i+1][j]=='.')||i==n)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]);}}}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<<j<<' '<<l<<' '<<up<<' '<<st<<' '<<dp[pre].sta[k]<<' '<<dp[pre].sum[k]<<endl;if(j==1&&up==1)dp[now].push(st|pybit(1,j),dp[pre].sum[k]);if(j!=m&&l==1&&up==0)dp[now].push(st|pybit(1,j),dp[pre].sum[k]);if(l==1&&up==2&&j==m)dp[now].push(st,dp[pre].sum[k]);}}for(int i=0;i<dp[now].size;i++)if(dp[now].sta[i]==0)ans+=dp[now].sum[i];return ans;}int main(){while(~scanf("%d%d",&n,&m)){if(n==0&&m==0) break;for(int i=1;i<=n;i++)scanf("%s",&gp[i][1]);lx=ly=0;for(int i=1;i<=n&&!lx;i++){for(int j=1;j<=m&&!lx;j++)if(gp[i][j]=='.')lx=i,ly=j;}//cout<<lx<<' '<<ly<<endl;cout<<DP()<<endl;}return 0;}