不是题目不会,而是思维方式有问题!!
1、Binary
【题目描述】
求所有可以用1和00拼成的长度为N的二进制数的个数除以15746的余数。
比如当 N=4的时候,有5 个可能的二进制: 0011, 0000, 1001, 1100, 1111。
【输入文件】
第一行一个正整数 N;
【输出文件】
输出所有可以只用1和00拼成的长度为N的二进制数的个数除以15746的
余数。
【输入输出样例】
输入
4
输出
5
【数据规模】
在 100%的数据中,1<=N<=1000000。
1.这不是个数学题!!!不是组合数学;
2.知道想法不对后,依旧从数学入手进行推导,距离std越来越远;
3.这个题目是跳楼梯的变式,竟然看不出来(递推题目一共才做了几道);…
std
典型递推题目,对于已经从一到五都已经列出来了还看不出规律表示无语;
规律的推导
对于当前的一种状态,只需加1或00就可以成为一个新的合法字符串;
同理可证 ,当前的合法串一定是从以前的某个串转移过来的;
ps,也可参考跳楼梯
n | tot | |
---|---|---|
1 | 1 | 1 |
2 | 11, 00 | 2 |
3 | 111 ,001 ,111 | 3 |
4 | 1111, 0011 ,1001,0011,0000 | 5 |
5 | 11111, 00111 ,10011,11001,11100,00001,10000,00100 | 8 |
6 | …………………. |
? 你看不出这是斐波那契数列
#include<iostream>
#include<cstdio>
using namespace std;
long long n,ans=1;
const int mo=15746;
int main(){
//freopen("binary.in","r",stdin);
//freopen("binary.out","w",stdout);
scanf("%d",&n);
int a=2,b=1;
if(n==2){
printf("2");
return 0;
}
for(int i=3;i<=n;i++)
{
ans=(a%mo+b%mo)%mo;
b=a;
a=ans;
}
printf("%d",ans);
return 0;
}