题目大意


数列k-bonacci (k is integer, k > 1)的定义如下:

  • F(k, n) = 0, for integer n, 1 ≤ n < k;
  • F(k, k) = 1;
  • F(k, n) = F(k, n - 1) + F(k, n - 2) + … + F(k, n - k), for integer n, n > k.

给出一个整数s,在数列中找出几个不同的元素使其和等于s。

思路


我们可以先暴力求出所有值小于s的元素,由题目input中给出的数据范围(1 ≤ s, k ≤ 10^9; k > 1)可以推知小于s的元素的数量不会很多。

求取结果是一个贪心的过程。由大到小遍历元素,如果当前元素不大于s,则将s减去此元素,并将此元素作为结果记录下来。重复上述步骤直至s等于0。

代码


#include<iostream>
#include<stdio.h>
#include<cstring>
using namespace std;

int f[100],res[100];
//f[i]表示f(k,k+i-1)
//res[]存储结果 
int N_f,N_res;
//N_f表示f[]中元素的数量
//N_res表示res[]中元素的数量 
int s,k;

void init()
//初始化 
{
	memset(f,0,sizeof(f));
	memset(res,0,sizeof(res));
}

void get_f()
//计算f[] 
{
	f[1]=1;
	//f(k,k)=1
	for(N_f=2;f[N_f-1]<=s;N_f++)
	//f[]中元素的值最大不超过s 
		for(int i=N_f-1;i>=1&&i>=N_f-k;i--)
			f[N_f]+=f[i];
}

void get_res()
//计算res[] 
{
	for(int i=N_f-1;i>=1&&s;i--)
		if(f[i]<=s)
		{
			res[N_res++]=f[i];
			s-=f[i];
		}
}

void input()
//输入 
{
	scanf("%d%d",&s,&k);
}

void output()
//输出
//每次都在结果末尾加一个0,避免结果数不足2的情况发生。 
{
	printf("%d\n",N_res+1);
	for(int i=0;i<N_res;i++)
		printf("%d ",res[i]);
	printf("0\n");
}

int main()
{
	init();
	input();
	get_f();
	get_res();
	output();
}