最近见到了好多跟排列有关的状压dp,好像略微会了一点,用 dp[i][s][j]表示第i位状态为s选择j的方案数,然后递推。
早起大概可以提高人的智商但是会导致人甚至不清,初始化写错了自闭了半个小时
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const ll mod = 1e9+7; 5 int n;string s; 6 int cal(int num){ 7 int res = 0; 8 while(num){ 9 res+=num%2; 10 num>>=1; 11 } 12 return res; 13 } 14 int dp[16][1<<16][16]; 15 int main(){ 16 ios::sync_with_stdio(false); 17 cin>>n>>s;s="**"+s; 18 for(int i=1;i<=n;i++){ 19 dp[1][1<<(i-1)][i]=1; 20 } 21 for(int i=2;i<=n;i++) { 22 for (int j=0;j<(1<<n); j++) { 23 if(cal(j)!=i)continue; 24 for(int k=1;k<=n;k++){ 25 if(!((1<<k-1)&j))continue; 26 for(int l=1;l<=n;l++) { 27 if(!((1<<l-1)&j))continue; 28 if (s[i]=='0') { 29 if(!(l==2*k||k==2*l)) 30 dp[i][j][k] += dp[i - 1][j ^ (1 << k - 1)][l]; 31 } else { 32 if((l==2*k||k==2*l)) 33 dp[i][j][k]+=dp[i-1][j^(1<<k-1)][l]; 34 } 35 dp[i][j][k]%=mod; 36 } 37 } 38 } 39 } 40 ll ans=0; 41 for(int k=1;k<=n;k++){ 42 ans=(ans+dp[n][(1<<n)-1][k])%mod; 43 } 44 cout<<ans<<endl; 45 }