原題鏈接
http://acm.hdu.edu.cn/showproblem.php?pid=1438
題面
題意
一把鎖匙有個槽,槽深爲。每鎖匙至少有個不同的深度且至少有對相連的槽其深度之差爲。求這樣的鎖匙的總數。
思路
因爲狀態只有位,所以考慮狀壓(暴力)
表示前i個槽深度爲且第個槽深度爲的數量,表示是否有相連的槽差爲。
參考代碼
/* CF was purple years ago!
* Thanks cf-tool!
* Author: nuoyanli
* Time: 2020-02-29 21:50:05
**/
#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false), cin.tie(0)
#define endl '\n'
#define PB push_back
#define FI first
#define SE second
#define m_p(a, b) make_pair(a, b)
#define lson l, mid, root << 1
#define rson mid + 1, r, root << 1 | 1
#define T(t) while (t--)
#define inf 0x3f3f3f3f
typedef long long LL;
const double pi = acos(-1.0);
const double eps = 1e-9;
const int N = 2e6 + 10;
const int M = 1e5 + 10;
const int mod = 1e9 + 7;
const int st = (1 << 10);
LL dp[1 << 5][1 << 4][1 << 2][1 << 1]; // dp[i][j][k][f]表示前i個槽深度爲j且第i個槽深度爲k的數量,f表示是否有相連的槽差爲3
void solve() {
IOS;
dp[1][1][0][0] = dp[1][2][1][0] = dp[1][4][2][0] = dp[1][8][3][0] = 1;//初始只有1 2 3 4這 四種狀態,分別用1 10 100 1000 表示
for (int i = 2; i < (1 << 5); i++) {
for (int j = 0; j < (1 << 4); j++) {
for (int k = 0; k < (1 << 2); k++) {
for (int st = 0; st < (1 << 2); st++) {
if (abs(st - k) == 3) {
dp[i][j | (1 << k)][k][1] += dp[i - 1][j][st][0];
} else {
dp[i][j | (1 << k)][k][0] += dp[i - 1][j][st][0];
}
dp[i][j | (1 << k)][k][1] += dp[i - 1][j][st][1];
}
}
}
}
cout << "N=2: 0" << endl;
for (int i = 3; i < (1 << 5); i++) {
LL ans = 0;
for (int j = 0; j < (1 << 2); j++) {
ans += (dp[i][7][j][1] + dp[i][11][j][1] + dp[i][13][j][1] + dp[i][14][j][1] + dp[i][15][j][1]);//至少存在三種不同的鑰匙的符合存在相連差爲3的數量 0111 1011 1101 1110 1111
}
cout << "N=" << i << ": " << ans << endl;
}
}
signed main() {
solve();
return 0;
}