本题算是状压dp的一个变形用法,在这里面将二进制位上的数从0变到1其实做得将牛放到末尾的操作,那么可以看到对于某一头牛他只关心前面一头牛是什么,前面牛到底有几种摆放方式和当前的牛无关。这符合动态规划的特性。
那么很容易得到状态转移方程为:dp[state|(1<<(i-1))][i] = dp[state|(1<<(i-1))][i]+dp[state][j]
值为方式数,放置的时候判断牛牛是否符合混乱即可。
//dp[state|(1<<(i-1))][i] = dp[state|(1<<(i-1))][i]+dp[state][j] #include <bits/stdc++.h> using namespace std; #define int long long const int maxn = 17; int dp[1<<16][maxn]; int num[maxn]; int n, k; signed main() { cin>>n>>k; for (int i=1;i<=n;i++) { cin>>num[i]; } for (int i=0;i<n;i++) { dp[1<<i][i+1] = 1; } int len = (1<<n)-1; for (int state=1;state<len;state++) { //遍历起点,一定是已经排过的牛 for (int i=1;i<=n;i++) { if (((state>>(i-1))&1)==0) continue; for (int j=1;j<=n;j++) { if ((state>>(j-1))&1) continue; if (abs(num[i]-num[j])<=k) continue; dp[state|(1<<(j-1))][j] = dp[state|(1<<(j-1))][j]+dp[state][i]; } } } int ans = 0; for (int j=1;j<=n;j++) { ans += dp[len][j]; } cout<<ans; return 0; }