CCF-有趣的数

最近浏览到CCF的题,刚开始做,做了前两道都没问题通过,第三道内存超限,90分。第四道,时间超时,10分。让我很郁闷。因此在网上百度了一下下。大部分的解决方案都是使用了动态规划的思想。大三学生,刚学了算法。编程中没有想到去使用它。说明我学的有多么烂了。目前的状态就是能看懂也能理解算法的思想,但是遇到问题想要去使用动态规划的时候,却没有思路。很郁闷。不知道该怎么解决这个问题。如果有大佬,还请不吝赐教。

步入正题,有趣的数。

给出题目:

试题名称: 有趣的数 

时间限制: 1.0s 

内存限制: 256.0MB 

问题描述: 问题描述

    我们把一个数称为有趣的,当且仅当:
    1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次。
    2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前。
    3. 最高位数字不为0。
    因此,符合我们定义的最小的有趣的数是2013。除此以外,4位的有趣的数还有两个:2031和2301。
    请计算恰好有n位的有趣的数的个数。由于答案可能非常大,只需要输出答案除以1000000007的余数。
    输入格式
      输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000)。
    输出格式
      输出只有一行,包括恰好n 位的整数中有趣的数的个数除以1000000007的余数。
    样例输入
      4
    样例输出

      3 

解题思路:

通过题目的规则。将其分为六个状态。很多人不知道六个状态是怎么想出来的。我也不知道,如果我能想出来也不必这么纠结了。但是搞明白了原因。在下面的分析中,我会忽略某些简单的问题,因为自己去思考效果更好。

状态1:首先,第一位只能为2。所以只使用了2的状态成为状态1

状态2:状态2和状态3可以一起考虑。第一位为2,或者说前面不管多少位只使用了2(013没有用到),那后续的数字可以为0或者3,状态2暂且定义为使用过2和0(13没有用到)

状态3:暂且定义为使用过2和3(01没有用到)

状态4:使用其中两个的结束之后应该是使用其中三个。使用过2和0之后,可以在使用1或者3都可以。使用过2和3之后只能使用0.因为0必须在1之前。这样又分化出两个状态。状态4定义为使用了2和0和3(1没有用到)

状态5:定义为使用了2和0和1(3没有用到)

状态6:三个数字全部用过之后,就是四个数字了。也就是0,1,2,3全部用到。定义为状态6.

 

6个状态分析结束了。可以发现有两个变量。一个是输入的位数。一个是四个数字分别出现的个数。

输入的位数不需要再说了。来看看这个个数怎么处理。

定义一个二维数组。横坐标表示输入的位数。纵坐标表示6个状态。

这样二维数组中右下角的数字就是满足题目要求的数字的个数。

在使用动态思想:最优解解是前n-1步的最优解+第n步的最优解

状态1(2)情况:   前n-1位只使用2(也就是状态1),第n位也只能使用2(为了满足状态1)

 

状态2(2,0)情况:前n-1位只使用2(也就是状态1),第n位使用0(变成状态2)或者前n-1位使用2 0(也就是原本就是状态2),第n位使用0或2  (仍然保证它是状态2)

 

状态3(2,3)情况:前n-1位只使用2(也就是状态1),第n位使用3(变成状态3)或者前n-1位使用2 3(也就是原本就是状态3),第n位使用3  (因为已经有了3了不能用2了,满足规则只能用3让它仍然保证是状态3)

 

状态4(2,0,3)情况: 前n-1位使用2 0(也就是状态2),第n位使用3(变成状态4)或者前n-1位使用2 3(也就是状态3),第n位使用0(变成状态4)或者前n-1位使用2 0 3(也就是原本就是状态4),第n位使用0或3 (因为已经有了3了不能用2了,满足规则只能用3让它仍然保证是状态4)(为了保证状态4,所以子状态不可能是状态1)


状态5(2,0,1)情况:前n-1位使用2 0(也就是状态2),第n位使用1(不使用3是为了让它满足状态5)或者 前n-1位使用2 0 1(也就是原本就是状态5),第n位使用1或2 (因为已经有了1了不能用0了,满足规则只能用1让它仍然保证是状态5)(为了保证状态5,所以子状态不可能是状态1或者状态3或者状态4)


状态6(2,0,1,3)情况: 前n-1位使用2 0 1(也就是状态5),第n位使用3(变成状态6)或者前n-1位使用2 0 3(也就是状态4),第n位使用1(变成状态6)或者前n-1位使用2 3 0 1(也就是原本就是状态6),第n位使用1或3(因为已经有了1,3了不能用0,2了,满足规则只能用1,3让它仍然保证是状态6)

不明白的可以留言。代码就不放了,百度一堆。此文仅帮助不能理解这6个状态的学者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值