posts - 43,  comments - 9,  trackbacks - 0

http://acm.scs.bupt.cn/onlinejudge/showproblem.php?problem_id=1586
题意:
一共有K(K<=50)种字母,组成一个长度为L(L<=10^18)的串.
这个串需满足要求:
对任意的 1<=i<=L , 以及任意的 1<=k1,k2<=K 且 k1!=k2, 在前缀 s[1..i]中,字母k1的个数和字母k2的个数之差的绝对值<=2.
例如: abac是合法的; 而abbbc不合法, 因为前缀abbb中字母b和c的个数相差为3.
建立状态:
从<=2 入手找状态. 可以设前c个字母中, 最小个数为m, 字母数为m的种类为i, m+1的种类为j, m+2的种类为k. 化简状态可得 比最小个数多1的种类为i,比最小个数多2的种类为j. 而经过数学推导(不懂), 可知 j+2k<K, 也就是当 c%K 已知时, 可直接由k确定i和j. 这样状态数为 50*50=2500, 还是不能用矩阵法. 进一步思考, 由c%K=0时的结果可以推出c%K=1时的结果,递推可把c%K=0...K-1的结果都求出. 而要求L步的结果数,实际上并不用去管是1步1步走,还是2步2步走. 所以我们可以直接一次走K步! 这样就把c%K这一维状态也消除了.
于是可以设矩阵m[i,j]为c%K=0时,k经过K步从i转移到j的方法数.
这样先求出 L-L%K 步的方法数, 最后 L%K 步直接dp即可.
整体复杂度为 K^3*log(L/K).

本题关键: 由k和c%K唯一确定i和j; 一次走K步, 消除状态c%K, 实际上不同c%K对应的状态是冗余的, 因为不用去管中间的过程.

posted on 2009-06-29 22:18 wolf5x 阅读(417) 评论(0)  编辑 收藏 引用 所属分类: acm_icpc

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

"Do not spend all your time on training or studying - this way you will probably become very exhausted and unwilling to compete more. Whatever you do - have fun. Once you find programming is no fun anymore – drop it. Play soccer, find a girlfriend, study something not related to programming, just live a life - programming contests are only programming contests, and nothing more. Don't let them become your life - for your life is much more interesting and colorful." -- Petr

留言簿(3)

随笔分类(59)

随笔档案(43)

cows

搜索

  •  

最新评论

评论排行榜