D5 F

最近见到了好多跟排列有关的状压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 }
View Code
原文地址:https://www.cnblogs.com/MXang/p/10336791.html