【刷题】【dp】蓝桥·回路计数
普通的哈密顿回路状态压缩模型,但是wa了两天
第一次是时间复杂度过大,调整了循环的嵌套顺序,由n*(1<<n)的复杂度改成了每个状态只遍历一次
f[1][1]=true; for(int i=1;i<n;i++) { int sz=st[i].size(); for(int j=0;j<sz;j++) { int sta=st[i][j]; for(int p=1;p<=n;p++) { if(!f[p][sta] ) continue; if((sta%mod[p+1]/mod[p])==0 ) continue; for(int q=1;q<=n;q++) { if(!g[p][q] ) continue; if((sta%mod[q+1]/mod[q])==1 ) continue; f[q][sta^mod[q]]+=f[p][sta]; } } } }
第二次是提交的时候只屏蔽了主函数,其他函数没删,莫名其妙运行错误了
所以蓝桥的填空题,代码要记得删干净啊
//n+1 + C(n+1,2) #include<bits/stdc++.h> #define ll long long using namespace std; inline int read() { int f=1,x=0; char c=getchar(); while(c<'0' || c>'9' ) { if(c=='-' ) f=-1; c=getchar(); } while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar(); return x*f; } int gcd(int a,int b) { if(a==0 ) return b; else return gcd(b%a,a); } const int n=21; const int mx=(1<<n)-1; bool g[30][30]; vector <int > st[30]; ll f[30][mx]; int mod[30]; int Cnt(int x) { int cnt=0; while(x ) { if((x&1)==1 ) cnt++; x>>=1; } return cnt; } int main() { cout<<881012367360; cout<<544071680; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j && gcd(i,j)==1 ) g[i][j]=true; for(int i=1;i<=mx;i++) st[Cnt(i)].push_back(i); mod[1]=1; for(int i=1;i<=n;i++) mod[i+1] = (mod[i]<<1); f[1][1]=true; for(int i=1;i<n;i++) { int sz=st[i].size(); for(int j=0;j<sz;j++) { int sta=st[i][j]; for(int p=1;p<=n;p++) { if(!f[p][sta] ) continue; if((sta%mod[p+1]/mod[p])==0 ) continue; for(int q=1;q<=n;q++) { if(!g[p][q] ) continue; if((sta%mod[q+1]/mod[q])==1 ) continue; f[q][sta^mod[q]]+=f[p][sta]; } } } } ll ans=0; for(int i=2;i<=n;i++) ans+=f[i][mx],cout<<" "<<f[i][mx]<<endl; cout<<ans<<endl; return 0; }