当前位置: 首页 > news >正文

[CF 2166D] Marble Council

思路

肯定是在值域上处理, 类似今年 S T4 的将与未扫描部分相关的部分单独统计
定义 \(c_x\)\(a_i = x\) 的数量
考虑 \(f_{i, j, k}\) 表示考虑到数字 \(i\), 当前要求容量到 \(j\), 当前容量为 \(k\) 的方案数

\[ \begin{gather*} c_i \times f_{i, j, k} \to f_{i + 1, j, k + c_i} \\ f_{i, j, k} \to f_{i + 1, \max(j, c_i), k} \end{gather*} \]

不难发现这个东西复杂度好像不怎么是 \(O(n^3)\)
发现 \(j \leq \sqrt{n}\), 因为 \(j\) 只能取出现过的 \(c_i\)
发现 \(i \leq 2\sqrt{n}\), 因为 \(< \sqrt{n}\) 的只有 \(\sqrt{n}\) 种, \(> \sqrt{n}\) 的最多出现 \(\sqrt{n}\)
所以复杂度是 \(\mathcal{O} (n^2)\)

#include <bits/stdc++.h>
using namespace std;
#define debug(...) fprintf(stderr, __VA_ARGS__)const int MOD = 998244353;int main() {// ios::sync_with_stdio(false);// cin.tie(nullptr);int t;cin >> t;while (t--) {int n;cin >> n;vector<int> a(n);for (int i = 0; i < n; i++) {cin >> a[i];}vector<int> cnt(n + 1, 0);for (int x : a) {cnt[x]++;}// 统计不同的出现次数并排序vector<int> values, freq;for (int i = 1; i <= n; i++) {if (cnt[i] > 0) {values.push_back(i);}}sort(values.begin(), values.end());values.erase(unique(values.begin(), values.end()), values.end());// 统计每种出现次数的频率// vector<int> freq(n + 1, 0);for (int i = 1; i <= n; i++) {if (cnt[i] > 0) {freq.push_back(cnt[i]);}}sort(freq.begin(), freq.end());freq.erase(unique(freq.begin(), freq.end()), freq.end());int m = values.size();int mm = freq.size();// dp[j_idx][k] - j_idx 是 values 中的索引,k 是当前容量vector<vector<int>> dp(mm + 1, vector<int>(n + 1, 0));// 初始状态:没有数字,要求容量为0,实际容量为0dp[0][0] = 1;int bababoy = 0;for (int val : values) {bababoy++;vector<vector<int>> new_dp(mm + 1, vector<int>(n + 1, 0));for (int j_idx = 0; j_idx <= mm; j_idx++) {int current_j = (j_idx == 0) ? 0 : freq[j_idx - 1];for (int k = 0; k <= n; k++) {if (dp[j_idx][k] == 0) continue;// 转移1: 将当前数字作为众数if (k + cnt[val] <= n) {new_dp[j_idx][k + cnt[val]] = (new_dp[j_idx][k + cnt[val]] + 1LL * dp[j_idx][k] * cnt[val]) % MOD;}// 转移2: 不将当前数字作为众数int new_j = max(current_j, cnt[val]);// 找到 new_j 在 freq 中的索引int new_j_idx = lower_bound(freq.begin(), freq.end(), new_j) - freq.begin() + 1;new_dp[new_j_idx][k] = (new_dp[new_j_idx][k] + dp[j_idx][k]) % MOD;}}dp = move(new_dp);// /*debug 所有有值的 dp 位置*/// for (int j_idx = 0; j_idx <= mm; j_idx++) {//     int j_val = (j_idx == 0) ? 0 : values[j_idx - 1];//     for (int k = 0; k <= n; k++) {//         if (dp[j_idx][k] > 0) {//             debug("dp[%d][%d][%d] = %d\n", bababoy, j_idx, k, dp[j_idx][k]);//         }//     }// }}// 统计所有满足 j <= k 的状态int ans = 0;for (int j_idx = 0; j_idx <= mm; j_idx++) {int j_val = (j_idx == 0) ? 0 : freq[j_idx - 1];for (int k = 0; k <= n; k++) {if (j_val <= k) {ans = (ans + dp[j_idx][k]) % MOD;}}}cout << ans << '\n';}return 0;
}

总结

dp 常用规模法理解

值域上处理和填一个坑的思想

http://www.jsqmd.com/news/43048/

相关文章:

  • DP 复习
  • 一段话 UOJ
  • PG系列:在 ​​psql​​ 客户端中定义参数与动态赋值
  • CF1375G Tree Modification 题解
  • AI评价11月17号
  • 避雷:aicodemirror.com --- 酒干倘卖无
  • 9-线性学习
  • AT AGC003 题解
  • Oracle故障处理:aix 5.3 ml6安装10.2.0.1 rac报错
  • Hive SQL循环与MapReduce的关系
  • 《算 设》学
  • [GESP202506 二级] 幂和数
  • hive mybatis是否支持动态SQL
  • 一类将度数变为 1/2 的优化建图 笔记
  • 2025.11.17模拟赛
  • 11/17
  • 英语_阅读_Electric cars_待读
  • linux 下中文字体安装.ttf 格式
  • 2025 年锚具厂家 TOP 企业品牌推荐排行榜,预应力锚具 / 五孔锚具 / 低回缩锚具 / 张拉锚具 / 固定端锚具 / 桥梁预应力锚具 / 边坡锚具公司推荐!
  • 2025 年锚具厂家 TOP 企业品牌推荐排行榜,桥梁伸缩缝 / 道路伸缩缝 / 梳齿板伸缩缝推荐这十家公司!
  • 2025 年锚具厂家 TOP 企业品牌推荐排行榜,橡胶支座 / 桥梁支座 / 国标支座 / 滑板支座 / 固定支座 / 弹性支座 / 活动铰支座 / 盆式支座 / 减震支座 / 缓冲支座公司推荐!
  • 软件工程学习日志2025.11.17
  • CSP2025 游记 + whk 期中
  • 论文速读 | 2025年11月
  • 2025-11-17
  • 九成九新自用C#入门文档
  • 商场展览车生产厂家十大排名及选购推荐,航利通达网红礼盒拖车公司,透明车厢生产厂家,车载展柜公司十大权威排行,商场展览车公司十大排名
  • Flask+Celery+Blueprint
  • 102302109-胡贝贝-作业3
  • hadoop linux 安装