专栏文章
题解:P1329 数列
P1329题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqazcwb
- 此快照首次捕获于
- 2025/12/04 01:50 3 个月前
- 此快照最后确认于
- 2025/12/04 01:50 3 个月前
设 表示 的方案数。转移是平凡的,与背包问题类似。
暴力的做法:假设所有数都是前一个数加一,即构造 ,总和就是 。将 减 会使所有数总和减少 ,所以目标就是用不同的 凑出 。这么做时间复杂度是 的,但可以用来输出方案(所以就出现了一道题正解中同时使用正解和暴力做法的情况)。
CPPconst ll N = 2000, S = 6000;
const lll mod = (lll)(1) << 64;
lll dp[N][S];
ll n, s, goal, cnt, ch[N];
void dfs(ll p, ll cur) {
if (cur > goal)
return;
elif(p > n) {
if (cur == goal) {
cnt++;
ll sum = 0;
rep(i, 1, n) {
sum += ch[i];
cout << sum << ' ';
}
endl;
if (cnt >= 100)
exit(0);
}
} else {
ch[p] = -1;
dfs(p + 1, cur + (n - p + 1));
ch[p] = 1;
dfs(p + 1, cur);
}
}
int main() {
cin >> n >> s;
if (abs(s) > n * (n - 1) / 2 or (n * (n - 1) / 2 - s) % 2) {
cout << 0;
return 0;
}
goal = (n * (n - 1) / 2 - s) / 2;
dp[1][0] = 1;
rep(i, 2, n) {
ll dis = n - i + 1;
cpy(dp[i], dp[i - 1]);
rep(j, dis, S - 1) (dp[i][j] += dp[i - 1][j - dis]) %= mod;
}
cout << (ull)(dp[n][goal]) << '\n';
dfs(2, 0);
}
代码宏定义在我个人空间自取。
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...