CDOJ 1133 菲波拉契数制 01背包

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;
			}
		}
	}
}

你可能感兴趣的:(CDOJ 1133 菲波拉契数制 01背包)