01背包版本的代码(一个01背包都改了好半天= =):
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
#define maxn 100005
int Fib[26];
int dp[26][maxn];
int main()
{
//freopen("input.txt", "r", stdin);
Fib[0] = 0, Fib[1] = 1, Fib[2] = 2;
for (int i = 3; i < 26; ++i)
Fib[i] = Fib[i - 1] + Fib[i - 2];
//printf("%d\n", Fib[25]);
for (int i = 1; i < 26; ++i)
dp[i][0] = 1;
//dp[1][1] = 1, dp[2][2] = 1;
int sum = 0;
for (int i = 1; i < 26; ++i)
{
for (int j = 1; j <= sum && j < maxn; ++j)
dp[i][j] = dp[i - 1][j];
sum += Fib[i];
for (int j = min(sum, maxn - 1); j >= Fib[i]; --j)
dp[i][j] = dp[i - 1][j] + dp[i][j - Fib[i]];
}
int T, n;
//printf("%d %d\n", dp[5][3], dp[5][11]);
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
printf("%d\n", dp[25][n]);
}
//system("pause");
//while (1);
return 0;
}
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
using namespace std;
int Fib[26];
int Num[100001];
int A[100001][26];
int dp[26][2];
void MakeFib();
void MakeAllNum();
int main()
{
int T, n;
memset(Fib, -1, sizeof(Fib));
memset(Num, -1, sizeof(Num));
memset(A, -1, sizeof(A));
MakeFib();
MakeAllNum();
scanf("%d", &T);
while (T--)
{
memset(dp, -1, sizeof(dp));
scanf("%d", &n);
dp[0][0] = A[n][0] / 2;
dp[0][1] = 1;
int i=-1;
for (i=1; i < 26; i++)
{
if (A[n][i] == -1)
break;
dp[i][1] = dp[i - 1][0] + dp[i - 1][1];
dp[i][0] = dp[i - 1][1] * (A[n][i] / 2) + dp[i - 1][0] * ((A[n][i] + 1) / 2);
}
printf("%d\n", dp[i - 1][1] + dp[i - 1][0]);
}
return 0;
}
void MakeFib()
{
Fib[0] = 0;
Fib[1] = 1;
Fib[2] = 2;
for (int i = 3; i < 26; i++)
{
Fib[i] = Fib[i - 1] + Fib[i - 2];
if (Fib[i]>100000)
break;
}
}
void MakeAllNum()
{
Num[0] = 0;
Num[1] = 1;
Num[2] = 1 << 1;
A[1][0] = 0;
A[2][0] = 1;
for (int i = 3; i <= 100000; i++)
{
int pos = 0;
for (int j = 2; j < 26; j++)
{
if (Fib[j] > i)
{
pos = j - 1;
break;
}
}
Num[i] = (1 << (pos - 1)) + Num[i - Fib[pos]];
int pot = 0;
int prepot = 0;
int set = 0;
for (int k = 1; k <= pos; k++)
{
if (Num[i] & (1 << (k - 1)))
{
pot = k;
A[i][set++] = pot - prepot-1;
prepot = pot;
}
}
}
}