惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
V2EX
WordPress大学
WordPress大学
U
Unit 42
I
InfoQ
A
About on SuperTechFans
宝玉的分享
宝玉的分享
J
Java Code Geeks
博客园 - 司徒正美
爱范儿
爱范儿
Engineering at Meta
Engineering at Meta
G
Google Developers Blog
人人都是产品经理
人人都是产品经理
小众软件
小众软件
Microsoft Security Blog
Microsoft Security Blog
L
LangChain Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hugging Face - Blog
Hugging Face - Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
aimingoo的专栏
aimingoo的专栏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
腾讯CDC
Recent Announcements
Recent Announcements

某岛

AtCoder Beginner Contest 409 Luogu P5325. 【模板】Min_25 筛 UOJ #188. 【UR #13】Sanrd AtCoder Beginner Contest 371 AtCoder Beginner Contest 369 RPGMaker 2k3 百科 OneShot 的考古 2024“开创拓芯”游戏创享节的相关记录 CJ 回来后的戒断反应 Luogu P10221. [省选联考 2024] 重塑时光 Luogu P5308 [COCI2018-2019#4] Akvizna wqs 二分 歌唱王国 Lean 相关 BZOJ 3153. Sone1 The 2023 ICPC World Finals Luxor 新巴别塔 Sora 的想象与思考 Facebook Hacker Cup 2023 Round 1 AtCoder Beginner Contest 322 LLaMA 2 相关 HuggingFace AI Game Jam ACL 2023 Trans 相关… Luogu P2053. [SCOI2007] 修车 Luogu P1973. [NOI2011] NOI 嘉年华 Luogu P1933. [NOI2010] 旅行路线 Luogu P1954. [NOI2010] 航空管制 Luogu P2048. [NOI2010] 超级钢琴 Luogu P2046. [NOI2010] 海拔
Codeforces Round #831
2022-11-05 · via 某岛

题意

给你一个含有 $n$ 个元素的可重集合 $A$,集合 $A$ 的每个元素是一个单元素集合 ${a_i}$。
定义一次操作由以下两步构成:

  • 选择 $A$ 中两个交集为空的集合 $S$, $T$。
  • 删除这两个集合,将它们的并添加进 $A$。

之后, 我们构造一个可重集合 $M$,表示当前剩下的所有集合的大小。
你可以执行任意多次操作,问所有不同的 $M$ 的总数。

做法

如果初始的元素互不相同,显然原问题等价于分拆数,虽然原问题是以合并的方式给出的。
那么原问题等价于带有某种限制的分拆数,限制为某些元素之间必须分拆。

分拆数我们知道有很多高级做法。。。比如欧拉五边形数、生成函数云云。。。。但是这个题 $n$ 只有 2000,大概率都用不到。

考虑分拆数最朴素的 DP。。。我们把分拆的结果按照从大到小排序。。那么每一种情况唯一对应一个单调递减且和为 n 的序列。
dp[i][s][j]: 当前考察前 i 个位置,和为 s 且末尾为 j 的方案数。
有:

const int N = int(1e3) + 9;
int dp[2][N][N];
int n;

int main() {
#ifndef ONLINE_JUDGE
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif
    RD(n);

    int p = 0, q = 1; RST(dp[p]); dp[p][0][n] = 1;

    REP_1(i, n) {
        swap(p, q); RST(dp[p]);
#define u dp[q][s][j]
#define v dp[p][s+k][k]
        REP(s, n+1) REP(j, n+1) if (u) {
            DWN_1(k, min(j, n-s), 0) v += u;
        }
        cout << dp[p][i][0] + 1 << " ";
    }
    cout << endl;
}

这个 DP 可以用部分和优化到 $O(n^3)$。
dp[i][s][j]: 当前考察前 i 个位置,和为 s 且末尾 >= j 的方案数。

const int N = int(1e3) + 9;
int dp[2][N][N];
int n;

int main() {
#ifndef ONLINE_JUDGE
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif
    RD(n);

    int p = 0, q = 1; RST(dp[p]); dp[p][0][n] = 1;

    REP_1(i, n) {
        swap(p, q); RST(dp[p]);
#define u dp[q][s][j]
#define v dp[p][s+j][j]
        REP(s, n+1) DWN(j, n+1, 0) u += dp[q][s][j+1];
        REP(s, n+1) REP(j, n+1) if (u) v += u;

        cout << dp[p][i][0] + 1 << " ";
    }
    cout << endl;
}

继续考察限制。。。结论是。。。它等价于 $s \leq \sum \min(i, c)$
其中 $c$ 遍历过初始集合中的每个元素出现的次数。。。

这个结论真的不是很显然。。。感觉需要用共轭的性质 + 各种归纳 yy 出来。。。
于是加上上面的限制作为剪枝就可以 O(n2logn) 跑出来。。。

但是我们知道其实分拆数的朴素 dp 可以进一步优化到 $O(n2)$。。。
原因是分差数本身就更特殊。。。状态可以进一步简化。。。

Posted by xiaodao
Category: 日常