P120练习赛

题目目录

  1. 交互题
  2. 提交答案题
  3. 传统题(提交答案)

第一题 交互题

题意

一句话题意:求把$n$拆成一些不同的斐波那契数之和的方案数。

$n\leq 10^{18}$。

题解

此题在洛谷上有原题。若想看详细题解,请转到这里

我们可以把$n$贪心拆为几个斐波那契数之和,然后对于每一个数,我们$dp_{i0}$和$dp_{i1}$表示$1-i$的数中$i$取或不取所能得到的方案数,然后答案就是$dp_{n0}+dp_{n1}$了。

附上代码:

#include <bits/stdc++.h>
#pragma GCC optimize("Ofast", "stack-protector-explicit") 
using namespace std;
#define int long long

int rd() {
	int ret=0;char ch;
	while(!isdigit(ch=getchar()));
	ret=ch-'0';while(isdigit(ch=getchar()))ret=ret*10+ch-'0';
	return ret;
}
void wd(int x) {
	printf("%lld\n",x);
}

int F[87]; int dp[87][2];
int T,n;
vector<int> A;

inline int R(int n) {
	A.clear();
	for (int i=86; i; i--) if (n >= F[i]) {
		A.push_back(i); n -= F[i];
	}
	sort(A.begin(), A.end());
	dp[0][0] = (A[0]-1)/2; dp[0][1] = 1;
	for (int i=1; i<A.size(); i++) {
		dp[i][1] = dp[i-1][0] + dp[i-1][1];
		dp[i][0] = dp[i-1][1] * ((A[i]-A[i-1]-1)/2) + dp[i-1][0] * ((A[i]-A[i-1])/2);
	}
	return dp[A.size()-1][0] + dp[A.size()-1][1];
}

signed main() {
	F[1] = 1; F[2] = 2;
	for (int i=3; i<=86; i++) F[i] = F[i-1] + F[i-2];
    
	T = rd();
	while (T--) {
		n = rd();
		wd(R(n));
	}
	return 0;
}

 

第三题 传统题(提交答案)

题意

一句话题意:每组数据给你小样例和大输入,让你求大输出。(都是数据结构的操作)

题解

image

posted @ 2018-07-25 20:38  MCH__ds  阅读(244)  评论(1编辑  收藏  举报