一维的01背包
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <queue>
#include <map>
#define FOP freopen("in","r",stdin)
#define inf 0x3f3f3f3f
#define ll __int64
#define eps 1e-8
using namespace std;
const int N = 100010;
int dp[N];
int fib[50];
int cnt;
void Init()
{
int tmp;
cnt = 0;
memset( fib , 0 , sizeof fib );
memset( dp , 0 , sizeof dp );
fib[cnt++] = 1;
fib[cnt++] = 2;
tmp = 3;
while( tmp < N )
{
fib[cnt++] = tmp;
tmp = fib[cnt-1] + fib[cnt-2];
}
}
void Pack()
{
int i,j;
dp[0] = 1;
for( i = 0 ; i < cnt ; i++ )
{
for( j = N-1 ; j >= fib[i] ; j-- )
{
dp[j] += dp[j-fib[i]];
}
}
}
int main()
{
int T,n;
Init();
Pack();
scanf( "%d" , &T );
while( T-- )
{
scanf( "%d" , &n );
printf( "%d\n" , dp[n] );
}
return 0;
}
dp[0] = 1这一步很妙,有了这一步可以简单的初始化dp数组所有元素为0,不用考虑两个加数是否都是fib数
原因如下,因为枚举的是fib数组,所以其中一个数肯定是fib数,而另一个数是不是fib数都无关紧要,我们只关心这个j-fib[i]拆成fib数一共有几种表达方法