1 条题解
-
0
C++ :
#include <cstdio> /* 最终结果 = Σ C(n-1,i) * p[i]。从左到右按值升序 DFS, 用「剩余系数 × 剩余可用值」的上下界剪枝,首个解即字典序最小。 */ static int n, used[13], perm[13], found; static long long target, coef[13]; void dfs(int p, long long cur){ if(found) return; if(p == n){ if(cur == target) found = 1; return; } int avail[13], ac = 0; for(int v = 1; v <= n; v++) if(!used[v]) avail[ac++] = v; /* 升序 */ long long cs[13]; int k = n - p; for(int i = 0; i < k; i++) cs[i] = coef[p + i]; for(int i = 0; i < k; i++) for(int j = i + 1; j < k; j++) if(cs[i] > cs[j]){ long long t = cs[i]; cs[i] = cs[j]; cs[j] = t; } long long mn = 0, mx = 0; /* 重排不等式:大系数配小值最小,大系数配大值最大 */ for(int i = 0; i < k; i++) mn += cs[k - 1 - i] * avail[i]; for(int i = 0; i < k; i++) mx += cs[i] * avail[i]; if(cur + mn > target || cur + mx < target) return; for(int i = 0; i < ac; i++){ int v = avail[i]; used[v] = 1; perm[p] = v; dfs(p + 1, cur + coef[p] * v); used[v] = 0; if(found) return; } } int main(){ long long sum; if(scanf("%d %lld", &n, &sum) != 2) return 0; target = sum; coef[0] = 1; for(int i = 1; i < n; i++) coef[i] = coef[i - 1] * (n - i) / i; for(int i = 1; i <= n; i++) used[i] = 0; found = 0; dfs(0, 0); if(found){ for(int i = 0; i < n; i++) printf("%d%c", perm[i], i + 1 == n ? '\n' : ' '); } return 0; }
- 1
信息
- ID
- 2835
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者