CCF有趣的数(快速幂,递推)
2016-04-09 17:35
246 查看
问题描述
我们把一个数称为有趣的,当且仅当: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
题解
一开始看这题真的是毫无头绪,后来尝试从一些很简单的问题入手,发现这个数只能以2开头,以1或3结尾,情况以下子少了很多,于是看看能不能递推,思路如下:- 设长度为n(n>=4)的有趣的数个数为a
- 考察a[n+1],
- 若这个数以1结尾
- 若前n位有0123,该情况数是a
- 若前n位没有1,设第一个3出现的位数是k(1≤k≤n-1,从左往右从1开始),该种情况方法数为2k−1×2n−k−1−1=2n−2−12^{k-1}×2^{n-k-1}-1=2^{n-2}-1,于是总的方法数为(n-1)(2n−2−12^{n-2}-1)
- 若这个数以3结尾
- 若前n位有0123,该情况数是a
- 若前n位没有3,情况略有不同,设第一个1出现的位数是k(2≤k≤n-1),该种情况方法数为(2k−1−1)×2n−k−1=2n−1−2n−k−1(2^{k-1}-1)×2^{n-k-1}=2^{n-1}-2^{n-k-1},于是总的方法数为∑n−1k=2(2n−1−2n−k−1)=(n−3)×2n−2+1\sum_{k=2}^{n-1}(2^{n-1}-2^{n-k-1})=(n-3)×2^{n-2}+1
- 综上,a[n+1]=2a
+(n-2)*2n−12^{n-1}-n+2
- 但是直接这么算,n稍微大一点就会溢出,因此要随时取模
/*a[n+1]=2a +(n-2)2^(n-1)-n+2*/ #include<stdio.h> #define m 1000000007 long long Pow(int n)/*计算2^n mod m*/ { if (n==1) return 2; long long half; half=Pow(n/2); if ((n&1)==0) return (half*half)%m; else return (((half*half)%m)*2)%m; } int main(void) { long long a=3; int i,n; scanf("%d",&n); for (i=4;i<n;i++) a=(a*2+(i-2)*Pow(i-1)-i+2)%m;/*可以保证在取余之前不会溢出,如果是int的话,(i-2)*Pow(i-1)可能会溢出*/ printf("%lld",a); return 0; }
相关文章推荐
- 记一次使用openrowset 的坑
- Python调用SQLPlus来操作和解析Oracle数据库的方法
- 将彩色图片转化为灰度图
- 将流信息转化成字符串
- Objective-C Runtime 运行时之四:Method Swizzling
- 这些Tips让你的App更容易维护
- c#代码阅读
- Android性能优化之内存优化练习
- SharedPreference.Editor的apply和commit方法异同
- Alembic 简明教程
- 面试常见题目:大数相加的Java实现(考虑负数情况)
- 第七周作业
- 欧姆龙CP1H的PLC步进功能图编程实例
- adb devices指令实例讲解
- adb devices指令实例讲解
- CentOS7编译安装Python2
- 指针与函数及数组
- 连接查询
- Objective-C Runtime 运行时之三:方法与消息
- 渗透入门