2013年12月CCF计算机软件能力认证 第四题 有趣的数(有限状态机)

我们把一个数称为有趣的,当且仅当:

  1. 它的数字只包含 0,1,2,3且这四个数字都出现过至少一次。
  2. 所有的 0都出现在所有的 1 之前,而所有的 2 都出现在所有的 3 之前。
  3. 最高位数字不为 0。

因此,符合我们定义的最小的有趣的数是 2013。

除此以外,4 位的有趣的数还有两个:2031 和 2301。

请计算恰好有 n 位的有趣的数的个数。

由于答案可能非常大,只需要输出答案除以 10^9+7 的余数。

输入格式

输入只有一行,包括恰好一个正整数 n。

输出格式

输出只有一行,包括恰好 n 位的整数中有趣的数的个数除以 10^9+7 的余数。

数据范围

4≤n≤1000

输入样例:

4

输出样例:

3

 思路:

考察有限状态机的转移:

我们不难发现只有六种情况:

0:只用了2 

1:  只用了2、0

2:只用了2、3 

3:  只用了2、0、3

4:只用了2 、0、1

5:  只用了2、0、1、3

可以用线性dp dp[n][i] 1<=i<=5 表示有n位 处于状态i的数目

状态转移我们随便举个例子分析一下,其他也是同样道理

比如dp[i][5]=(dp[i-1][3]%mod+dp[i-1][4]%mod+dp[i-1][5]*2%mod)%mod; 因为前面2013全有 所以下一位只能放 1 3;也可能是4状态转移过来 那就是填3;也可能是3状态填1转移过来

#include<bits/stdc++.h>
using namespace std;
const int N=1010,mod=1e9+7;
int dp[N][6],n;
int main(){
    cin>>n;
    dp[1][0]=1;
    for(int i=2;i<=n;i++){
        dp[i][0]=dp[i-1][0]%mod;
        dp[i][1]=(dp[i-1][0]%mod+dp[i-1][1]*2%mod)%mod;
        dp[i][2]=(dp[i-1][0]%mod+dp[i-1][2])%mod;
        dp[i][3]=(dp[i-1][1]%mod+Xdp[i-1][2]%mod+dp[i-1][3]*2%mod)%mod;
        dp[i][4]=(dp[i-1][1]%mod+dp[i-1][4]*2%mod)%mod;
        dp[i][5]=(dp[i-1][3]%mod+dp[i-1][4]%mod+dp[i-1][5]*2%mod)%mod;
    }
    cout<<dp[n][5]%mod<<endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值