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

School Team Contest 2 (Winter Computer School 2010/11) - I. Toys(受限增长字符串)

原题链接:I. Toys

题目大意

玛莎将 nnn 个玩具(编号隐含为 1∼n1\sim n1n)分成若干堆,哥哥萨沙却把所有玩具合并成了一堆。为哄玛莎开心,萨沙需要尝试所有可能的玩具分堆方式,直到玛莎认可;且每次调整只能进行 单次操作(从任意一堆取一个玩具,移到另一堆,或单独成为一个新堆),要求每个分堆方式仅尝试一次,初始状态为所有玩具在同一堆。

样例输入
第一行输入为测试样例个数

3

样例输出

5
{1,2,3}
{1,2},{3}
{1},{2,3}
{1},{2},{3}
{1,3},{2}

题目分析

对于一个集合的分区,可以用一个字符串来编码,这个字符串被称为受限增长字符串。

  • 受限增长字符串:对于字符串 a1,a2,…,ana_1,a_2,\dots,a_na1,a2,,an,它满足 a1=0a_1=0a1=0aj+1≤1+max⁡(a1,…,aj)a_{j+1}\le1+\max(a_1,\dots,a_j)aj+11+max(a1,,aj)。当且仅当元素 iiijjj 在分区中属于同一个子集时,它们在字符串中对应的字符相等。例如,分区 {1,3},{2},{4}\{1,3\},\{2\},\{4\}{1,3},{2},{4} 的字符串表示为 010201020102

吉迪恩 - 埃利希发明了一种简便方法来建立受限增长字符串列表,以下简称 埃利希方案

假设已经有了长度为 n−1n-1n1 的受限增长字符串列表 s1,s2,…,sks_1,s_2,\dots,s_ks1,s2,,sk,需要从中得到长度为 nnn 的列表。对于 si=a1a2…an−1s_i=a_1a_2\dots a_{n-1}si=a1a2an1,令 m=1+max(a1,…,an−1)m=1+max(a_1,\dots,a_{n-1})m=1+max(a1,,an1)。如果 iii 为奇数,将数字 0,m,m−1,…,1,0,m,m-1,\dots,1,0,m,m1,,1, 依次追加到 sis_isi 后面,得到长度为 nnn 的字符串;如果 iii 为偶数,则按照 1,…,m−1,m,01,\dots,m-1,m,01,,m1,m,0 的顺序追加数组。该算法的时间复杂度为 O(n⋅B(n))O(n\cdot B(n))O(nB(n)),其中 B(n)B(n)B(n) 为贝尔数,是超指数级的增长速度,当 n=10n=10n=10 时约为 10510^5105

代码答案

#include<bits/stdc++.h>
#define endl '\n'
#define pb push_back
#define all(x) x.begin(), x.end()using namespace std;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vstr = vector<string>;// 埃利希方案生成所有长度为 n 的受限增长字符串
vstr Init(int n) {if(n == 1) return {"0"};auto pre = Init(n - 1);vstr res;for(size_t i = 0; i < pre.size(); i++) {auto &s = pre[i];int m = *max_element(all(s)) - '0' + 1;vi app = {0};for(int k = m; k >= 1; k--) app.pb(k);if(i & 1) {for(int j = m; j >= 0; j--) res.pb(s + char('0' + app[j]));} else {for(int j = 0; j <= m; j++) res.pb(s + char('0' + app[j]));}}return res;
}int main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int n; cin >> n;vstr s = Init(n);cout << s.size() << endl;for(size_t i = 0; i < s.size(); i++) {vvi q;for(int j = 1; j <= n; j++) {int pos = s[i][j - 1] - '0';if(q.size() == pos) q.pb({j});else q[pos].pb(j);}for(size_t j = 0; j < q.size(); j++) {cout << '{';for(size_t k = 0; k < q[j].size(); k++) cout << q[j][k] << ",}"[k == q[j].size() - 1];cout << ",\n"[j == q.size() - 1];}}return 0;
}
http://www.dtcms.com/a/471587.html

相关文章:

  • H.265/HEVC NALU结构快速入门:从起始码到Type值识别
  • 初中电脑做网站的软件wordpress商品采集
  • 焦作网站建设哪家公司好网站页面分辨率
  • asp.net 网站建设方案做网站用不用thinkphp
  • Tool Calling和本地MCP服务的调用
  • 陕icp网站建设厦门seo公司网站
  • 商城网站建设目标网站的收费窗口怎么做
  • 长春模板网站建设企业怎样提高网站访问速度
  • 怎么评估一个对象的边界很复杂?代码与指标
  • 计算机基础·数据库系统原理
  • 网站开发vs平台的功能第一素材网
  • 2019网站seo免费学设计的网站
  • 网站同城在线哪里做怀化建设企业网站
  • 营销网站域名设计建设网站需要收费吗
  • LFM2 模型介绍
  • JAVA:DecimalFormat的DEMO(格式化数字)
  • 专业的网站设计制作公司廊坊北京网站建设
  • Python Requests库用法示例:从入门到实战的HTTP请求指南
  • 番禺建网站网站建设的流程分析
  • 婚庆设计网站模板做框架表格网站
  • 敦化建设局网站两学一做纪实评价系统登陆网站
  • 依托 <AI 原生应用架构白皮书>,看 AI 原生应用的发展与实践
  • 重庆卓光网站建设外贸网站支付系统
  • 西安制作网站需要多少钱网站图片大小多少合适
  • 网站开发后端所需要的语言南和邢台网站制作
  • SpringBoot集成:5分钟实现HTML转PDF功能
  • 深圳外贸网站推广公司学做网站书籍
  • 做直播网站视频教程大连网络运营
  • 凤岗做网站国家工商网查询企业信息
  • 个人项目开发(1):使用Spring Secruity实现用户登录