【题目描述】
众所周知,HYF有很多小姊妹。 HYF每天放学之后都要跟(不同的)MM约会。HYF这天约会的时候不巧被jzt撞上了……虽然换一个新的MM约会这种事情对于HYF来说如同家常便饭,所谓“好事不出门,坏事传千里”,jzt迅速将这个消息传播开来。 每个听到这个消息的人首先会震惊一段时间(他怎么又换MM了- -~!),但是这样的震惊只会持续2个时刻(因为这对于HYF来说太正常了= =~!)。如果他在第i个时刻听到这个消息,就会从第(i+2)个时刻开始传播这个消息,每个时刻把这个消息告诉两个人,当然他只会告诉不知道这个消息的人。但是当他连续告诉了10个人之后,他就会口干舌燥,停止传播。 jzt在第0时刻撞到HYF(当然jzt也有震惊时间),请问第N时刻共有多少人知道了这个消息?【Sample Input】(一行一个整数N,表示第N时刻)
【输入样例1】4
【输入样例2】1
【输入样例3】10【Sample Output】(一行一个整数,表示N分钟后知道这个消息的总人数)
【输出样例1】11
【输出样例2】1
【输出样例3】651【数据规模】
20%的数据,N<=20
60%的数据,N<=1000
100%的数据,N<=10000
【题解】递推+高精压位
递推应该是比较好想的,f[i]=(f[i-2]+f[i-3]+…+f[i-6])*2,当然想要再进一步合并也可。
高精的话注意极限情况的位数就好了。大概2000+位吧。
#include <cstdio>
#include <iostream>
#define bit 1000000
#define LL long long
struct num{ LL l,a[500];};
int n;num ans,a[10005];
num operator +(num x,num y)
{
x.l=std::max(x.l,y.l);
for (int i=1;i<=x.l;++i) x.a[i]+=y.a[i];
for (int i=1;i<=x.l;++i)
x.a[i+1]+=x.a[i]/bit,x.a[i]%=bit;
if (x.a[x.l+1]) ++x.l;
return x;
}
num operator *(num x,int y)
{
for (int i=1;i<=x.l;++i) x.a[i]*=y;
for (int i=1;i<=x.l;++i)
x.a[i+1]+=x.a[i]/bit,x.a[i]%=bit;
if (x.a[x.l+1]) ++x.l;
return x;
}
void print(num x)
{
printf("%d",x.a[x.l]);
for (int i=x.l-1;i;--i) printf("%.6d",x.a[i]);
}
int main()
{
scanf("%d\n",&n);
a[0].a[1]=a[0].l=1;
for (int i=1;i<=n;++i)
for (int j=std::max(0,i-6);j<=i-2;++j) a[i]=a[i]+a[j]*2;
for (int i=0;i<=n;++i) ans=ans+a[i];
print(ans);
return 0;
}