ccf201312-4有趣的数,递推

http://115.28.138.223/view.page?gpid=T2

问题描述

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

  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

0在1之前,2在3之前,0123至少出现一次。由题意开头的数只能是2。

从最高位开始,一位一位的递推,不过需要递推多个情况来得出结论。

根据条件,第i位(i>0)可能出现的情况有:


假设第i位已知


前i位之前出现的数

(其他在第i位数之前未出现)


0


因为第一位为2,所以必然有2出现


0,1


a[i]


2


a[i+1]


=


a[i]


b[i]


0,2


b[i+1]


=


b[i]+b[i]+a[i]


c[i]


2,3


c[i+1]


=


c[i]+a[i]


d[i]


0,2,1


d[i+1]


=


d[i]+d[i]+b[i]


e[i]


0,2,3


e[i+1]


=


e[i]+e[i]+c[i]+b[i]


f[i]


2,3,0,1


f[i+1]


=


f[i]+f[i]+d[i]+e[i]

以此得到递推公式。

另外,可以通过数列的相关知识,求得一个f[i]关于i的公式,将算法的复杂度直接从O(n)降到O(1),这大概才是最佳的答案吧。

题目得到的结果比较大,可以边加边求余,不影响结果。

C语言代码

#include <stdio.h>

long long a,b,c,d,e,f;
long long ta,tb,tc,td,te,tf;

int main(){
    int i=0,num;
    a=b=c=d=e=f=g=h=0;

    a++;//第一位为2
    scanf("%d",&num);
    for(i=1;i<num;i++){//从第二位开始求解,循环num-1次
        //ta=a;
        tb=b+b+a;
        tc=c+a;
        td=d+d+b;
        te=e+e+c+b;
        tf=f+f+d+e;

        //a=ta%1000000007LL;
        b=tb%1000000007LL;
        c=tc%1000000007LL;
        d=td%1000000007LL;
        e=te%1000000007LL;
        f=tf%1000000007LL;
    }
    printf("%d",f);
}
时间: 2024-10-05 23:50:51

ccf201312-4有趣的数,递推的相关文章

cf166e 在四面体上寻找路线数 递推,取模

来源:codeforces                 E. Tetrahedron You are given a tetrahedron. Let's mark its vertices with letters A, B, C and D correspondingly. An ant is standing in the vertex D of the tetrahedron. The ant is quite active and he wouldn't stay idle. At

Buy the Ticket(卡特兰数+递推高精度)

Buy the Ticket Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1886 Accepted Submission(s): 832   Problem Description The \\\\\\\"Harry Potter and the Goblet of Fire\\\\\\\" will be on show i

3930: [CQOI2015]选数|递推|数论

题目让求从区间[L,H]中可重复的选出n个数使其gcd=k的方案数 转化一下也就是从区间[?Lk?,?Hk?]中可重复的选出n个数使其gcd=1的方案数 然后f[i]表示gcd=i的方案数,考虑去掉所有的数都是重复的情况,这种情况最后在判断一下加上 f[i]=sum?∑i|jf[j] #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<c

BZOJ 3930: [CQOI2015]选数 递推

3930: [CQOI2015]选数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id=3930 Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研究.然而他很快发现工作量太大了,于是向你寻求帮助

NPU 2015年陕西省程序设计竞赛网络预赛(正式赛)F题 和谐的比赛(递推 ||卡特兰数(转化成01字符串))

Description 今天西工大举办了一场比赛总共有m+n人,但是有m人比较懒没带电脑,另外的n个人带了电脑.不幸的是,今天机房的电脑全坏了只能用带的电脑,一台电脑最多两人公用,确保n>=m.但是大家来的时间不同,随机次序来机房,带电脑的人直接准备比赛而没带电脑的人需要向带电脑并还没和别人公用的人求助(当然会答应).但是,如果不存在带电脑并还没和别人公用的人,那他就要等了,等是很让人头疼的,这就不和谐了,当然假如没有这样的情况发生比赛是很和谐的. Input 输入多组数据,每组数据只有一行m(

uva 1478 - Delta Wave(递推+大数+卡特兰数+组合数学)

题目链接:uva 1478 - Delta Wave 题目大意:对于每个位置来说,可以向上,水平,向下,坐标不能位负,每次上下移动最多为1, 给定n问说有多少种不同的图.结果对10100取模. 解题思路:因为最后都要落回y=0的位置,所以上升的次数和下降的次数是相同的,并且上升下降的关系满足出栈入栈的关系.即卡特兰数. 所以每次枚举i,表示有i个上升,i个下降,用组合数学枚举出位置,然后累加求和. C(2?in)?f(i)=C(2?i?2n)?f(i?1)?(n?2?i+1)?(n?2?i+2)

数的计数——递推算法

Problem Description 我们要求找出具有下列性质数的个数(包括输入的自然数n).先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理: 不作任何处理: 在它的左边加上一个自然数,但该自然数不能超过原数的一半: 加上数后,继续按此规则进行处理,直到不能再加自然数为止. Input 输入有多组数据,每组数据为自然数n. Output 对于每组数据输出满足条件的数的个数. Sample Input 6 Sample Output 6 Hint 满足条件的数为6,16

1025 数的划分(搜索和递推方法)

难度:普及/提高- 题目类型:递推 提交次数:3 涉及知识:动规 题目描述 将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序). 例如:n=7,k=3,下面三种分法被认为是相同的. 1,1,5; 1,5,1; 5,1,1; 问有多少种不同的分法. 输入输出格式 输入格式: n,k (6<n<=200,2<=k<=6) 输出格式: 一个整数,即不同的分法. 搜索: 代码: 1 #include<iostream> 2 using namespace std

hdu4165(简单递推,实则卡特兰数的应用)

这道题之前自己做的时候并没有反应过来是求卡特兰数,当时是按递推来想的.后来查了下HDU4165,结果一看大标题就说是卡特兰数,自己想了想,还真是那么回事.主要还是对于卡特兰数用的不多,也就当时没立马反应过来了.下面介绍这道题我的思路,然后对卡特兰数再做一些补充. 本题题意:罐子里有N片相同的药片,开始的时候药片都是完整的一整片.然后一个每天从中任意取一片,如果该药片是完整的一整片,那么他会吃点半片,然后将剩余半片扔回罐里,如果恰好是半片,那他直接吃掉拿出来的半片.显然2N天后,他吃完全部N片药片