CCF-CSP 201312-4 有趣的数 [c++]

博客详细介绍了如何解决CCF CSP 201312-4问题,即有趣的数。文章讨论了有趣数的定义,并通过动态规划方法来构建递推公式,包括S[n]、S012[n]、S023[n]、S23[n]和S02[n]等子问题的解决。最后,给出了实现这些递推公式的C++代码。
摘要由CSDN通过智能技术生成

CCF-CSP 201312-4 有趣的数

问题描述

题目链接

思路

首先整理一下有趣的数的定义:
1.只包含数字0、1、2和3
2.0、1、2和3各自至少出现一次
3.所有的0都出现在1之前
4.所有的2都出现在3之前
5.最高位数字不为0

上述定义可以看出,有趣数以1或3结尾,以2开始。
遇到这类题容易想到动态规划。(取一个大数的余就有暗示动规的意味)。但是想了很久都没有想到解法,原因是没有考虑设置子目标进行多目标动规。现将答案的思路重新整理如下:

  1. 定义 S [ n ] S[n] S[n]为恰好n 位的整数中有趣的数的个数。定义 s [ n ] s[n] s[n]为字符串形式的 n n n位有趣的数的实例。 T [ n ] T[n] T[n]为n 位有趣的数的集合。显然有 S [ n ] = ∣ T [ n ] ∣ S[n] = |T[n]| S[n]=T[n] + + +表示数字字符串的拼接。
  2. 本题与常见的动态规划的差别在于需要用到一些的子目标,与 S [ n ] S[n] S[n]同时动规求解,且多个目标之间的关系我们希望是线性关系。(否则取余就不能在动规过程中进行,这就失去了意义)
  3. 得出递归公式的过程是不停地分析和拆解目标并建立子目标的过程。
  4. 寻找 S [ n ] S[n] S[n] S [ n − 1 ] S[n-1] S[n1]的关系。
    1. 首先 s [ n − 1 ] + 1 ∈ T [ n ] s[n-1] + 1 \in T[n] s[n1]+1T[n] s [ n − 1 ] + 3 ∈ T [ n ] s[n-1] + 3 \in T[n] s[n1]+3T[n]。这样就把 T [ n ] T[n] T[n]中1和3结尾的情况考虑完了。
    2. 但1和3结尾的情况并未考虑完全。如 20113 ∈ T [ 5 ] 20113 \in T[5] 20113T[5],但 2011 ∉ T [ 4 ] 2011 \notin T[4] 2011/T[4],故存在一种由0,1,2组成的结构(0,1,2各自至少出现一次,且0在1的前面),在它后面加上3就可以得到有趣数。将这种数定义为 s 012 [ n ] s_{012}[n] s012[n]。同理存在一种由0,2,3组成的数(0,2,3各自至少出现一次,且2在3的前面)在它后面加上3就可以得到有趣数。将这种数定义为 s 023 [ n ] s_{023}[n] s023[n]。这就是前面说的子目标。于是可以得到如下递推式。 S [ n ] = 2 S [ n − 1 ] + S 012 [ n − 1 ] + S 023 [ n − 1 ] S[n] = 2S[n-1] +S_{012}[n-1]+S_{023}[n-1] S[n]=2S[n1]+S012[n1]+
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值