gan这两题怎么差不多
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; bool u[5100]; LL f[20][5100]; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0)break; int li=(1<<m)-1; for(int i=0;i<=li;i++) { int cc=0;u[i]=true; for(int j=m-1;j>=0;j--) if(i&(1<<j)) { if(cc%2==1)u[i]=false; cc=0; } else cc++; if(cc%2==1)u[i]=false; } //-------------------------- memset(f,0,sizeof(f));f[0][0]=1; for(int i=1;i<=n;i++) for(int zt=0;zt<=li;zt++) for(int lzt=0;lzt<=li;lzt++) if((lzt&zt)==0&&u[lzt|zt]==true) f[i][zt]+=f[i-1][lzt]; printf("%lld ",f[n][0]); } return 0; }
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; char ss[110][20]; int b[110]; int f[2][2100][2100]; int len,z[2100],d[2100]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%s",ss[i]+1); for(int i=1;i<=n;i++) { b[i]=0; for(int j=1;j<=m;j++) if(ss[i][j]=='H')b[i]^=(1<<(j-1)); } int li=(1<<m)-1;len=0; for(int i=0;i<=li;i++) { int cc=-3,dd=0;bool bk=true; for(int j=0;j<=m-1;j++) if(i&(1<<j)) { if(j-cc<=2){bk=false;break;} cc=j;dd++; } if(bk==true){z[++len]=i;d[len]=dd;} } //-------------------------- int now=0,ans=0;f[now][0][0]=1; for(int i=1;i<=n;i++) { now^=1; for(int j=1;j<=len;j++) if(i==1||(!(z[j]&b[i-1]))) { for(int k=1;k<=len;k++) if( (!(z[k]&b[i])) && (!(z[j]&z[k])) ) { f[now][j][k]=0; for(int p=1;p<=len;p++) if( (i<=2||(!(z[p]&b[i-2]))) && (!(z[j]&z[p])) && (!(z[k]&z[p])) ) { f[now][j][k]=max(f[now][j][k],f[now^1][p][j]+d[k]); } ans=max(ans,f[now][j][k]); } } } printf("%d ",ans); return 0; }
同样0/1区分特殊位置,同样预处理当前行的合法状态,同样用位运算判断合法
还是插头DP有意思哈哈,还很快哩
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; const LL mod=10007; struct Plug_DP { LL f[5100]; int top;LL sta[5100],hash[5100]; void pha(LL s,LL sum) { LL x=s%mod; while(hash[x]!=0&&sta[hash[x]]!=s)x=(x+1)%mod; if(hash[x]==0)sta[++top]=s,hash[x]=top; f[hash[x]]+=sum; } void clean() { top=0; memset(hash,0,sizeof(hash)); memset(f,0,sizeof(f)); } }dp[2]; LL get_bracket(LL s,LL p) { return ((s>>(p-1))&1); } LL set_bracket(LL s,LL p,LL v) { s^=(get_bracket(s,p)<<(p-1)); s^=(v<<(p-1)); return s; } int n,m;LL ans; void Plug_DP() { int pre=0,now=1; dp[now].clean();dp[now].pha(0,1); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { swap(pre,now);dp[now].clean(); for(int k=1;k<=dp[pre].top;k++) { LL s=dp[pre].sta[k],sum=dp[pre].f[k]; LL p=get_bracket(s,j),q=get_bracket(s,j+1); if(i==n&&j==m) { if((p==1&&q==0)||(p==0&&q==1))ans+=sum; continue; } if(p==0&&q==0) { if(i!=n) { s=set_bracket(s,j,1); s=set_bracket(s,j+1,0); dp[now].pha(s,sum); } if(j!=m) { s=set_bracket(s,j,0); s=set_bracket(s,j+1,1); dp[now].pha(s,sum); } } if((p==1&&q==0)||(p==0&&q==1)) { s=set_bracket(s,j,0); s=set_bracket(s,j+1,0); dp[now].pha(s,sum); } } } for(int k=1;k<=dp[now].top;k++)dp[now].sta[k]<<=1; } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0)break; ans=0;Plug_DP(); printf("%lld ",ans); } return 0; }