P4133 [BJOI2012]最多的方案(记搜)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4133 [BJOI2012]最多的方案(记搜)相关的知识,希望对你有一定的参考价值。

P4133 [BJOI2012]最多的方案(记搜)

记搜,因为 f i f_i fi递增很快, f i f_i fi的个数不会很多。

从大到小考虑每个 f i f_i fi是否可选。预处理 f i , s i f_i,s_i fi,si s i s_i si f i f_i fi的前缀和。

d f s ( n , m ) dfs(n,m) dfs(n,m)表示对于当前 n n n考虑第 m m m f i b o n a c c i fibonacci fibonacci数,若 f [ m ] > n f[m]>n f[m]>n显然不考虑,若 s m − 1 < n s_{m-1}<n sm1<n 显然 f m f_m fm需要选,不然即使后面都选了也不能满足条件。

递归终止条件是: n = = 0 ∣ ∣ m = = 1 n==0||m==1 n==0m==1 返回 n = = 0 n==0 n==0

这里 m = 1 m=1 m=1是因为题目要求每个方案都不能有相同的数, f 1 = f 2 = 1 f_1=f_2=1 f1=f2=1

所以 f 2 f_2 f2是最后一个选择。

玄学复杂度。

// Problem: P4133 [BJOI2012]最多的方案
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4133
// Memory Limit: 125 MB
// Time Limit: 500 ms
// Date: 2021-08-24 15:00:47
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=105,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
ll f[N],s[N];
map<pair<ll,int>, ll>mp;
ll dfs(ll n,int m){
	if(!n||m==1) return !n;
	pair<ll,int> p={n,m};
	if(mp.count(p)) return mp[p];
	if(f[m]>n) return mp[p]=dfs(n,m-1);
	if(s[m-1]<n) return mp[p]=dfs(n-f[m],m-1);
	return mp[p]=dfs(n,m-1)+dfs(n-f[m],m-1);
}
int main(){
	f[1]=f[2]=s[1]=1,s[2]=2;
	for(int i=3;i<=87;i++) s[i]=s[i-1]+(f[i]=f[i-1]+f[i-2]);
	ll n;scanf("%lld",&n);
	printf("%lld\\n",dfs(n,87));
	return 0;
}

以上是关于P4133 [BJOI2012]最多的方案(记搜)的主要内容,如果未能解决你的问题,请参考以下文章

[BJOI2012]最多的方案(记忆化搜索)

bzoj2660: [Beijing wc2012]最多的方案

bzoj 2660: [Beijing wc2012]最多的方案

bzoj 2660: [Beijing wc2012]最多的方案dp

bzoj千题计划213:bzoj2660: [Beijing wc2012]最多的方案

P2476 [SCOI2008]着色方案(记搜&多维dp)