洛谷P4133 [BJOI2012]最多的方案(记忆化搜索)
题意
求出把$n$分解为斐波那契数的方案数,方案两两不同的定义是分解出来的数不完全相同
Sol
这种题,直接爆搜啊。。。
打表后不难发现$<=1e18$的fib数只有88个
最先想到的应该是直接把$n$加入到搜索状态里,然后枚举能被分成哪些
但是这样分解出来的数可能会有重复的,因此我们还要把当前考虑到第几个数也加入到状态里。
不难得到以下代码

但是很显然会T飞。
优化一下,只考虑当前的fib数对答案的贡献,
也就是搜两种情况:
1、用该数分解
2、不用该数分解
代码是这样的

然而还是会T飞。
继续剪枝。
根据斐波那契的性质$\sum_{i = 1}^n f_i = f_{n+2} -1$
因此我们想要用前$ti - 1$个合成$x$,必须满足$x < f_{ti+1}$。
然后就A了qwq
// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
#include<map>
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
#define int long long
#define ull unsigned long long
using namespace std;
const int MAXN = 1e5 + ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int f[MAXN], tot, lim, dp[MAXN], N;
map<Pair, int> mp;
int dfs(int x, int ti) {
if(mp.find(MP(x, ti)) != mp.end()) return mp[MP(x, ti)];
if(x == ) return ;
int ans = ;
/*for(int i = ti; i >= 1; i--) {
if(x - f[i] >= 0) ans += dfs(x - f[i], i - 1);
//else break;
}*/
if(x - f[ti] >= ) ans += dfs(x - f[ti], ti - );
if(x < f[ti + ])
ans += dfs(x, ti - ); return mp[MP(x, ti)] = ans;
}
main() {
lim = 1e18;
f[] = ; f[] = ;
for(int i = ; i; i++) {
f[i] = f[i - ] + f[i - ];
if(f[i] > lim) {tot = i; break;}
}
N = read();
//dp[0] = 1;
cout << dfs(N, tot - );
return ;
}
洛谷P4133 [BJOI2012]最多的方案(记忆化搜索)的更多相关文章
- 【题解】洛谷P3953 [NOIP2017TG] 逛公园(记忆化搜索+SPFA)
		
题目来源:洛谷P3953 思路 先用SPFA求一遍最短路 在求最短路的同时可以把所有点到终点的最短路求出来 dis数组 注意要反向SPFA 因为从起点开始可能会走到一些奇怪的路上导致时间负责度增加 ...
 - 洛谷1514 引水入域 dp+记忆化搜索
		
题目链接:https://www.luogu.com.cn/problem/P1514 题意大致是:给定一个(n,m)的数值矩阵,可以在第一行建造水库,如果一个格子周围的某格子值小于它,那水就可以流到 ...
 - BZOJ 1079: [SCOI2008]着色方案 记忆化搜索
		
1079: [SCOI2008]着色方案 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
 - SCOI2008着色方案(记忆化搜索)
		
有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i 种颜色的油漆足够涂ci 个木块.所有油漆刚好足够涂满所有木块,即 c1+c2+...+ck=n.相邻两个木块涂相同色显得很难 ...
 - BZOJ1079: [SCOI2008]着色方案 (记忆化搜索)
		
题意:有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得很 ...
 - 洛谷 P3953 逛公园【spfa+记忆化dfs+bfs】
		
spfa预处理出最短路数组dis,然后反向建边bfs出ok[u]表示u能到n点 然后发现有0环的话时候有inf解的,先dfs找0环判断即可 然后dfs,设状态f[u][v]为到u点,还可以跑最短路+v ...
 - bzoj1079   着色方案      记忆化搜索(dp)
		
题目传送门 题目大意: 有k种颜色,每个颜色ci可以涂个格子,要求相邻格子颜色不能一样,求方案数.ci<=5,k<=15. 思路: 题目里最重要的限制条件是相邻格子颜色不能相同,也就是当前 ...
 - 【P2476】着色方案(记忆化搜索+特殊的DP数组)
		
这个题代码难度几乎为0,然而思维难度对于蒟蒻来说简直是突破天际啊!首先我思考的是这个油漆的种类只有15种,是不是可以像一道叫做8数码难题的东西暴力15维数组呢..计算发现不可以....空间会直接让你学 ...
 - 洛谷 [BJOI2012]最多的方案
		
洛谷 这题是旁边同学介绍的,听他说记忆化搜索可以过... 不过我还是老老实实的想\(dp\)吧- 先看看数据范围,\(n\leq10^{18}\)相当于\(n \leq fib[86]\). 以前打\ ...
 
随机推荐
- iconv字符转换
			
iconv是linux下的编码转换的工具,它提供命令行的使用和函数接口支持 函数接口 iconv函数族的头文件是iconv.h,使用前需包含之.#include <iconv.h> ico ...
 - 8、泛型程序设计与c++标准模板库2.2向量容器
			
向量容器属于顺序容器,用于容纳不定长线性序列(即线性群体),提供对序列的快速随机访问(也称直接访问).这一点与c++语言支持的基本数组类型相同,但基本数据类型不是面向对象的.而面向对象的向量是动态结构 ...
 - spring framework 源码
			
spring framework 各版本源码下载地址 现在spring的源码下载地址真是不好找,这次终于找到了.记录一下,以帮助需要的朋友. https://github.com/spring-pro ...
 - windows下编译Boost库
			
下载源码 boost_1_66_0.7z 生成编译工具 D:\Project\boost_1_66_0> bootstrap.bat 配置Python环境变量(使用VS2017自带的32位pyt ...
 - Python包管理工具setuptools之setup函数参数详解
			
**********************************************************对所学内容的简单汇总******************************** ...
 - Java8 使用 stream().filter()过滤List对象(查找符合条件的对象集合)
			
内容简介 本文主要说明在Java8及以上版本中,使用stream().filter()来过滤一个List对象,查找符合条件的对象集合. List对象类(StudentInfo) public clas ...
 - Unity3D -- shader常用函数和变量
			
最近在学习Unity Shader,写Shader的时候总是忘记Unity为我们提供的函数.变量怎么写的,这里整理一下,方便自己查阅,也提供给网友,学习Shader不易. 1.函数 float3 Wo ...
 - mybatis笔记 - 初始配置及dao的封装
			
1.用户实体类 package com.javasm.entity; /** * *TODO 用户表实体类 * @author CaoLei 2018年6月26日上午10:50:12 * Manage ...
 - 《OD学hadoop》20160904某旅游网项目实战
			
一.ETL操作 抽取数据 日志格式: 分割符号:^A IP地址 服务器时间 二.Java工程 1. 创建项目 copy代码及配置文件 2. 改配置 core-site.xml hbase-site.x ...
 - 二维偏序 tree
			
tree(二维偏序) 最近接触到一些偏序的东西. 传统线段树非叶子节点的划分点mid=(l+r)/2,但小R线段树mid是自己定的.但满足l<=mid<r,其余条件同原来线段树.那么不难发 ...