constint N = 11; int n, a[N], ans; int group[N][N], cnt[N];
intgcd(int a, int b){ return a ? gcd(b%a, a) : b; }
boolcheck(int g, int x){ for (int i = 0; i < cnt[g]; i++) { if (gcd(group[g][i], x) != 1) returnfalse; } returntrue; }
voiddfs(int u, int k){ if (k >= ans) return; if (u == n) { ans = k; return; } for (int i = 0; i < k; i++) { if (check(i, a[u])) { group[i][cnt[i]++] = a[u]; dfs(u+1, k); cnt[i]--; } } group[k][cnt[k]++] = a[u]; dfs(u+1,k+1); cnt[k]--; }
intmain(){ cin >> n; ans = n; for(int i = 0; i < n; i++) cin >> a[i]; dfs(0, 0); cout << ans << endl; return0; }
// 寻找能放数字最少的点 int minv = 10, x = -1, y = -1; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (str[i*9+j] == '.' && ones[state(i, j)] < minv) { minv = ones[state(i, j)]; x = i, y = j; } // 去掉最后一位 lowbit 用 i -= lowbit(i) for (int i = state(x, y); i; i -= lowbit(i)) { int j = logtwo[lowbit(i)]; put(x, y, j, false); if (dfs(n-1)) returntrue; put(x, y, j, true); }
returnfalse; }
intmain(){ // 打表 for (int i = 0; i < N; i++) logtwo[1 << i] = i; for (int i = 0; i < M; i++) for (int j = i; j; j -= lowbit(j)) ones[i]++; while (cin >> str, str[0] != 'e') { init();
int cnt = 0; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) if (str[i*9+j] == '.') cnt++; elseput(i, j, str[i*9+j]-'1', false); dfs(cnt); cout << str << '\n'; }
constint M = 21; int n, m, R[M], H[M], minv[M], mins[M]; int ans = 2e9;
voiddfs(int u, int s, int v){ if (v + minv[u] > n) return; if (s + mins[u] >= ans) return; if (s + 2*(n-v)/R[u+1] >= ans) return; if (u == 0) { // 体积必须刚好用完 if (v == n) ans = s; return; } for (int r = min(R[u+1]-1, (int)sqrt(n-v)); r >= u; r--) { // 如果想用 Ru 剪枝 就在这里 // if (ans < s + 2*(n-v)/r) continue; for (int h = min(H[u+1]-1, (n-v) / r / r); h >= u; h--) { R[u] = r, H[u] = h; int extra = 0; if (u == m) extra = r*r; dfs(u-1, s+extra+2*r*h, v+r*r*h); R[u] = H[u] = 0; } } }
intmain(){ cin >> n >> m; for (int i = 1; i <= m; i++) { minv[i] = i*i*i + minv[i-1]; mins[i] = 2*i*i + mins[i-1]; } R[m+1] = H[m+1] = 2e9; dfs(m, 0, 0); if (ans == 2e9) ans = 0; cout << ans << '\n'; return0; }
// 四带 for (int i = 2; i <= 14; i++) { if (cnt[i] < 4) continue;
// 带两对 for (int j = 2; j <= 14; j++) { if (j == i || cnt[j] < 2) continue; for (int k = 2; k <= 14; k++) { if (k == i || k == j || cnt[k] < 2) continue;
// 散牌 for (int i = 2; i <= 16; i++) if (cnt[i]) u++; ans = min(ans, u); }
intmain(){ scanf("%d%d", &T, &n); while (T--) { ans = 25; memset(cnt, 0, sizeof cnt); for (int i = 0; i < n; i++) { int a, b; scanf("%d%d", &a, &b); // a: 2 ~ 16 if (a == 1) a = 14; if (a == 0 && b == 1) a = 15; if (a == 0 && b == 2) a = 16; cnt[a]++; } dfs(0); printf("%d\n", ans); } return0; }
voiddfs(){ // 能填的数量最小的 int x = -1, y = -1; for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) if (!g[i][j] && (x == -1 || ones[state(i, j)] < ones[state(x, y)])) x = i, y = j; if (x == -1) { int t = 0; for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) t += score[i][j] * g[i][j]; ans = max(ans, t); return; } int s = state(x, y); for (int i = 9; i >= 1; i--) { if (s >> (i-1) & 1) { put(x, y,i); dfs(); put(x, y, i, true); } } }
intmain(){ for (int i = 0; i < 1 << 9; i++) ones[i] = countones(i); for (int i = 0; i < 9; i++) num[1<<i] = i+1; // init for (int i = 0; i < 9; i++) row[i] = col[i] = block[i%3][i/3] = (1 << 9) - 1;
for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) { int v; scanf("%d", &v); if (v) put(i, j, v); } dfs(); printf("%d\n", ans); return0; }
voiddfs(int x, int y, int u, int d, int cnt){ if (x < 0 || x >= n || y < 0 || y >= m || g[x][y] != s[u]) return; if (u == L-1) { ans++; return; } dfs(x+dx[d], y+dy[d], u+1, d, cnt); if (u && !cnt) for (int i = 0; i < 2; i++) dfs(x, y, u, d^2^(i<<2), cnt+1); }
intmain(){ cin >> s >> n >> m; L = strlen(s); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> g[i][j]; } } for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) for (int k = 0; k < 8; k++) dfs(i, j, 0, k, 0); printf("%d\n", ans); return0; }
booldfs(int u, int depth){ // 可行性剪枝 if (u == depth) return a[u-1] == n; // 排除等效冗余 bool st[N] = {0}; for (int i = u-1; i >= 0; i--) { for (int j = i; j >= 0; j--) { int s = a[i]+a[j]; // 可行剪枝 & 冗余剪枝 if (s > n || st[s] || s <= a[u-1]) continue; a[u] = s; if (dfs(u+1, depth)) returntrue; a[u] = 0; } } returnfalse; }
intmain(){ a[0] = 1; while (cin >> n, n) { int depth = 1; while (!dfs(1, depth)) depth++; for (int i = 0; i < depth; i++) cout << a[i] << ' '; cout << '\n'; } return0; }
// 大棒数量 当前木棒长度 开始枚举坐标 booldfs(int u, int s, int start, int length){ // 如果数量从 0 开始,那么这里就是 u * length // 因为 0 ~ u-1 一共有 u 个木棒 // 但是这里我选择 u = 1 开始,这样就要乘当前木棒的长度了 if (u * s == sum) returntrue; // 开新棒 if (s == length) returndfs(u+1, 0, 0, length); // 优化搜索顺序 for (int i = start; i < n; i++) { if (st[i]) continue; // 可行性剪枝 if (s + w[i] > length) continue; st[i] = true; if (dfs(u, s+w[i], i+1, length)) returntrue; st[i] = false; // 3-2 int j = i; while (j < n && w[j] == w[i]) j++; i = j-1; // 3-3 if (s == 0) returnfalse; // 3-4 if (s + w[i] == length) returnfalse; } returnfalse; }
intmain(){ while (cin >> n, n) { sum = 0; memset(st, 0, sizeof st); for (int i = 0; i < n; i++) { cin >> w[i]; sum += w[i]; } // 优化搜索顺序 sort(w, w+n, greater<int>()); for (int length = 1; length <= sum; length++) { // 可行性剪枝 if (sum % length == 0 && dfs(1, 0, 0, length)) { cout << length << endl; break; } } } return0; }
constint N = 46; int n, m, k, w[N]; int ans, weights[1 << (N/2)], cnt;
voiddfs1(int u, int s){ if (u == k) { weights[cnt++] = s; return; } // 防止溢出, w[u]+s <= m if (w[u] <= m-s) dfs1(u+1, s+w[u]); dfs1(u+1, s); }
voiddfs2(int u, int s){ if (u == n) { int l = 0, r = cnt-1; while (l < r) { int mid = l+r+1 >> 1; if (weights[mid] <= m-s) l = mid; else r = mid-1; } ans = max(ans, weights[l]+s); return; } if (w[u] <= m-s) dfs2(u+1, s+w[u]); dfs2(u+1, s); }
intmain(){ cin >> m >> n; k = n >> 1; for (int i = 0; i < n; i++) cin >> w[i]; sort(w, w+n, greater<int>()); dfs1(0, 0); sort(weights, weights+cnt); cnt = unique(weights, weights+cnt) - weights; dfs2(k, 0); cout << ans << endl; return0; }
intf(){ int total = 0; for (int i = 1; i < n; i++) { if (q[i] != q[i-1]+1) total++; } return (total + 2) / 3; }
booldfs(int u, int depth){ // IDA*: 可行性剪枝 if (f() + u > depth) returnfalse; if (f() == 0) returntrue; for (int len = 1; len <= n; len++) { for (int l = 0; l+len-1 < n; l++) { int r = l+len-1; // r-l+1 = len for (int k = r+1; k < n; k++) { memcpy(bak[u], q, sizeof q); // bak[u][r+1~k] -> q[l~?] // bak[u][l~r] -> q[?~k] int x = l, y = r+1; while (y <= k) q[x++] = bak[u][y++]; y = l; while (y <= r) q[x++] = bak[u][y++]; if (dfs(u+1, depth)) returntrue; memcpy(q, bak[u], sizeof q); } } } returnfalse; }
intmain(){ int T; cin >> T; while (T--) { cin >> n; for (int i = 0; i < n; i++) cin >> q[i]; int depth = 0; while (depth < 5 && !dfs(0, depth)) depth++; if (depth == 5) cout << "5 or more\n"; else cout << depth << '\n'; } return0; }
intf(){ int cntn[4] = {0}, maxv = -1; for (int i = 0; i < 8; i++) { int n = a[mid[i]]; cntn[n]++; maxv = max(maxv, cntn[n]); } return8-maxv; }
voidmove(int sln[]){ int head = a[sln[0]]; for (int i = 0; i < 6; i++) a[sln[i]] = a[sln[i+1]]; a[sln[6]] = head; }
booldfs(int u, int depth, int last){ if (f() == 0) returntrue; if (u + f() > depth) returnfalse; for (int i = 0; i < 8; i++) { if (opposite[i] == last) continue; move(op[i]); ans[cnt++] = i; if (dfs(u+1, depth, i)) returntrue; ans[cnt--] = 0; move(op[opposite[i]]); } returnfalse; }
intmain(){ while (cin >> a[0], a[0]) { cnt = 0; for (int i = 1; i < N; i++) cin >> a[i]; int depth = 0; while (!dfs(0, depth, -1)) depth++; if (depth == 0) printf("No moves needed"); elsefor (int i = 0; i < cnt; i++) printf("%c", ans[i]+'A');
constint N = 10; char g[N][N]; char dest[N][N] = { "11111", "01111", "00*11", "00001", "00000", }; int dx[8] = {-1, -1, -2, -2, 1, 1, 2, 2}; int dy[8] = {2, -2, 1, -1, 2, -2, 1, -1}; int lim;
intf(){ int res = 0; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (g[i][j] != dest[i][j]) res++; } } returnmax(res-1, 0); }
booldfs(int u, int x, int y){ int v = f(); if (v == 0) returntrue; if (u == lim || v + u > lim) returnfalse;
for (int i = 0; i < 8; i++) { int nx = x+dx[i], ny = y+dy[i]; if (nx < 0 || nx >= 5 || ny < 0 || ny >= 5) continue; swap(g[x][y], g[nx][ny]); if (dfs(u+1, nx, ny)) returntrue; swap(g[x][y], g[nx][ny]); } returnfalse; }
intmain(){ int T; scanf("%d", &T); while (T--) { int x = -1, y = -1; for (int i = 0; i < 5; i++) { scanf("%s", g[i]); for (int j = 0; j < 5; j++) { if (g[i][j] == '*') x = i, y = j; } }
bool found = false; for (lim = 0; lim <= 15; lim++) if (dfs(0, x, y)) { found = true; printf("%d\n", lim); break; } if (!found) puts("-1"); } return0; }
intdfs(int x, int y){ if (x < 1 || x > r || y < 1 || y > c) { return0; } int res = 0; int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}; for (int i = 0; i < 4; i++) { int nx = x + dx[i], ny = y + dy[i]; if (a[nx][ny] < a[x][y]) res = max(dfs(nx, ny), res); } return res + 1; }
intmain(){ cin >> r >> c; for (int i = 1; i <= r; i++) for (int j = 1; j <= c; j++) cin >> a[i][j]; int ans = 0; for (int i = 1; i <= r; i++) for (int j = 1; j <= c; j++) ans = max(ans, dfs(i, j)); cout << ans << endl; return0; }
intdfs(int x, int y){ if (x < 1 || x > r || y < 1 || y > c) { return0; } if (f[x][y]) return f[x][y]; int res = 0; int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}; for (int i = 0; i < 4; i++) { int nx = x + dx[i], ny = y + dy[i]; if (a[nx][ny] < a[x][y]) res = max(dfs(nx, ny), res); } f[x][y] = res + 1; return res + 1; }
没有上司的舞会
Ural 大学有 N 名职员,编号为 1∼N。他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。每个职员有一个快乐指数,用整数 Hi 给出,其中 1<=i<=N。
intdfs(int u, bool choose){ if (f[u][choose]) return f[u][choose]; int res = choose ? happy[u] : 0; for (int i = h[u]; i != -1; i = ne[i]) { int j = e[i]; if (choose) { res += dfs(j, false); } else { res += max(dfs(j, false), dfs(j, true)); } } f[u][choose] = res; return res; }
intmain(){ cin.tie(0), cout.tie(0), ios::sync_with_stdio(false); cin >> n; memset(h, -1, sizeof h); for (int i = 1; i <= n; i++) cin >> happy[i]; for (int i = 0; i < n-1; i++) { int p, c; cin >> c >> p; add(p, c); hasfather[c] = true; } int root = -1; // 这里要从 1~n,因为遍历的是每个节点 for (int i = 1; i <= n; i++) { if (!hasfather[i]) { root = i; break; } } cout << max(dfs(root, true), dfs(root, false)) << '\n'; return0; }