《Balance》解题报告.pdfVIP

  1. 1、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
《Balance》解题报告

《Balance》解题报告 中山纪念中学 梁健楠 【题源】 本题来自CODEFORCES 17C—— 《Balance》。 【前言】 本题是一道DP题,巧妙地设计状态以及转移方法。主要考验同学的思维能力。 【题目大意】 给定一串长度为n 150,只包含abc 三种字符的字符串s,能对其进行两种 操作: 1,选相邻的两个字符,将后面的字符变成前面的字符,如:ab 变成aa; 2,选相邻的两个字符,将前面的字符变成后面的字符,如:ab 变成bb。 记|a|,|b|,|c|分别为字符串s 中a,b,c 出现的个数。定义平衡字符串 必须同时满足-1 |a|- |b| 1,-1 |a|- |c| 1,-1 |b|- |c| 1。 问:字符串s 通过若干次操作后,能变换成多少个不同的平衡字符串。 样例输入: 样例输出: Case 1: Case 1: 4 7 abca Case 2: Case 2: 3 4 Case 3: abbc 1 Case 3: 2 ab 【问题分析】 首先忽略对新字符串|a|,|b|,|c|限制,思考原字符串s 与转换后新字符串 s1 的关系。 原串s 中某一位置上的字符能通过操作将新串s1 中任意位置更新为该字符。 定义序列g(i)表示新串s1 中第i位字符是从原串s 中第g(i)位字符更新过来的。 可得性质:对于任意i j,有g(i) g(j)。也就是说,序列g 是不下降序列。 而同一个新字符串s1可能对应很多种不同的g序列,现在规定两个限制:1) 新串s1 中相邻两个字符相同的位置i 和i+1,限定g(i)=g(i+1);2)新串s1 中 相邻两个字符不相同的位置 i 和 i+1,限定原串s 中第g(i)至g(i+1)位之间不 存在与第 g(i+1)位字符相同的字符(即g(i+1)是 g(i)位后不同字符出现的最先 位置),这样能使得一个新字符串s1 对以一种g 序列。 根据上述限制,设计DP,f[i][na][nb][nc]表示新字符串长度为na+nb+nc, 其中a,b,c 字符分别出现na,nb,nc 次,g(na+nb+nc)=i 的字符串数。 先预处理出next 数组,next[i][ch]表示原字符串第 i 位后字符ch 最先出 现的位置。 转移时,枚举下一位字符,并根据规定的限制更新 i(要注意状态枚举的顺 序)。 假如统计出所有新字符串,那么 na,nb,nc 最大能达到 n,算法的时间复杂 度和空间复杂度都会达到O(n^4)。 考虑用对新字符串|a|,|b|,|c|的限制来优化,要保证-1 |a|- |b| 1, -1 |a|- |c| 1,-1 |b|- |c| 1,那么|a|,|b|,|c|最大只有(n+2)/3。这样 na,nb,nc 也只需枚举到(n+2)/3。 最后统计所有满足na+nb+nc=n 且-1 na-nb 1,-1 na-nc 1,-1 nb-nc 1 的状态的和。 至此,算法的时间复杂度为O(n* (n/3)^3),能在规定时间内求得解。 【程序实现(pascal)】 const maxp var N,M,i,a,b,c,ans:longint; ch:array[0..155]of char; f:array[0..155,0..55,0..55,0..55]of longint; next:array[0..155,0..3]of longint; begin readln(N); for i:=1 to N do read(ch[i]); readln;

文档评论(0)

baoyue + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档