Codeforces225B - Well-known Numbers
阿新 • • 發佈:2018-03-13
正整數 std () IT set 方法 lin ORC 數列
Portal
Description
定義\(k\)-bonacci數列\(\{F_n\}\):\(F_i=0 \ (i<k),F_i=1 \ (i=k),F_i=\sum_{j=i-k}^{i-1}F_j\)
給出\(s(s\leq10^9)\)和\(k(k\leq10^9)\),將\(s\)拆成若幹個\(k\)-bonacci數之和。
Solution
結論:重復從\(s\)中減掉最大的\(F_i\),一定能使\(s=0\)。
可以用數學歸納法證明。
若對於正整數\(k\),\(\forall s\in [0,F_k-1]\)該結論成立,則\(\forall s\in [F_k,F_{k+1}-1]\),其下最大的\(F_i\)為\(F_k\),而\(s-F_k\in [0,F_{k-1}-1]\),其必然也能按上述方法減至0。
而因為\(k=1\)時該結論成立,所以\(\forall s\)該結論均成立。
Code
//Well-known Numbers
#include <cstdio>
#include <algorithm>
using namespace std;
int const N=1e5+10;
long long f[N];
int n,m,ans[N];
int main()
{
int s,k; scanf("%d%d",&s,&k);
int n; f[1]=1;
for(n=2;f[n-1]<s;n++)
for(int j=max(1,n-k);j<=n-1;j++) f[n]+=f[j];
int m=0;
for(int i=n-1;i>=1&&s;i--) if(f[i]<=s) ans[++m]=f[i],s-=f[i];
if(m<2) ans[++m]=0;
printf("%d\n",m);
for(int i=1;i<=m;i++) printf("%d ",ans[i]);
puts("");
return 0;
}
P.S.
看標簽猜結論系列binary search
greedy
number theory
。不過根本不需要binary search
啊!
Codeforces225B - Well-known Numbers