Luogu P4133 [BJOI2012] 最多的方案 题解

news/2025/2/19 15:38:25/文章来源:https://www.cnblogs.com/bluewindde/p/18717747

记忆化搜索,设 \(f(x, k)\) 表示当前考虑 \(F_k\),需要分解的数是 \(k\),分类讨论

  • \(x = 0\),则 \(f(x, k) = 1\)
  • \(k = 1\),则 \(f(x, k) = 0\)
  • \(x < F_k\),则 \(f(x, k) = f(x, k - 1)\)
  • \(x > F_1 + F_2 + F_3 + \cdots + F_{k - 1} = F_{k + 1} - 1\),则 \(f(x, k) = f(x - F_k, k - 1)\),因为此时不分解出 \(F_k\) 就一定无解;
  • 否则,\(f(x, k) = f(x - F_k, k - 1) + f(x, k - 1)\)

这个做法很轻松地通过了所有数据,我们如何知道它的时间复杂度?

考虑势能分析,设 \(\Phi(n, k)\) 表示计算 \(f(x, k)\)\(x\) 的最大可能值。

断言:要么 \(\Phi(n, k) < F_{k + 1}\),要么 \(\Phi(n, k)\) 在常数次迭代内可以满足前述情况。

证明

边界情况令 \(\Phi(n, k) = n\),接下来假设 \(k > 2\)

考虑在转移过程中说明断言成立。

  • \(x < F_k\),则 \(\Phi(n, k - 1) < F_k\) 满足断言;
  • 否则,分类 \(f(x, k) = f(x, k - 1) + f(x - F_k, k - 1)\) 中的两项。注意此时 \(F_k \leqslant x < F_{k + 1}\),所以
    1. 对于 \(f(x - F_k, k - 1)\),有 \(0 \leqslant x - F_k < F_{k - 1}\),满足断言。进一步,其继续迭代一次仍满足断言;
    2. 对于 \(f(x, k - 1)\),下一次迭代必然走向 \(f(x - F_{k - 1}, k - 2)\),此时 \(F_{x - 2} \leqslant x - F_{k - 1} < F_{k - 1}\) 满足断言。

Q.E.D.

推论

\(\phi = \frac {\sqrt 5 - 1} 2\),则每两次迭代至少使势能变为原来的 \(2 \phi^2 \approx 0.764\)

证明

继续上一个证明的分类讨论:

  • 第一类情况中,一次迭代使得势能变为原来的 \(\phi\),两次即为 \(\phi^2\)
  • 第二类情况中,两次迭代使得势能变为原来的 \(2 \phi^2\),两种子情况分别贡献 \(\phi^2\)
  • 特殊地,如果第一类情况后接着第二类情况,三次为 \(2 \phi^3\),平均一次 \((2 \phi^3)^{\frac 2 3} = \sqrt[3]4 \phi^2 < 2 \phi^2\)

Q.E.D.

所以,总迭代次数约为 \(O(-\log_{2 \phi^2}(n)) \sim O(\log_{1.309}(n))\),时间复杂度正确。

#include <iostream>
#include <map>using namespace std;typedef long long i64;const i64 lim = 1e18;int tail;
i64 fib[100];
i64 f[100];map<pair<i64, int>, int> mp;
static inline i64 dfs(i64 x, int k) {if (!x)return 1;if (k == 1)return 0;if (mp.count({x, k}))return mp[{x, k}];if (x < fib[k])return mp[{x, k}] = dfs(x, k - 1);if (f[k - 1] < x)return mp[{x, k}] = dfs(x - fib[k], k - 1);return mp[{x, k}] = dfs(x, k - 1) + dfs(x - fib[k], k - 1);
}signed main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);fib[1] = fib[2] = 1;for (tail = 2; fib[tail] <= lim; ++tail)fib[tail + 1] = fib[tail] + fib[tail - 1];for (int i = 1; i <= tail; ++i)f[i] = f[i - 1] + fib[i];i64 n;cin >> n;cout << dfs(n, tail) << '\n';return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/884538.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

容器

容器 mapfirst:代表键 second:代表值 遍历也可以使用迭代器来访问插入删除(erase)===> 返回删除元素的数量查找功能findupper_bound(返回的迭代器是指向键值大于所给定值的第一个元素) 找到所有价格小于等于 6.8 的商品lower_bound(返回的迭代器是指向键值不小于所给…

【Atcoder训练记录】AtCoder Beginner Contest 393

训练情况忙着处理训练数据,赛后打的,没有排名 赛后反思 这场太典了,感觉我能力范围内都是一眼题,剩下的真不会了 A题 显然有问题的就是 sick或fine补集,对应的交集,如果交集为空答案就是 4,我们直接大力分类讨论,fine fine是 4,sick fine是 2,fine sick是 3,sick si…

C#的GC垃圾回收

空间分配 在讨论垃圾回收之前,需要明白一个重要的事情,空间是怎么被分配出去的。在进程初始化时,CLR会保留一块连续的地址空间(托管堆),托管堆中维护着一个指针,称之为NextObjPtr,它指向下一个对象在堆中的分配位置。当我们在C#中调用new关键字的时候,编译器会自动生成…

ConcurrentHashMap(JDK1.8)put分析

一、ConcurrentHashMap整体结构 ConcurrentHashMap的数据结构与HashMap差不多,都是Node数组+红黑树+链表;ConcurrentHashMap中table的节点类型有 3 类:Node节点,是链表类型的节点;这类节点hash 大于 0 ;在扩容时ConcurrentHashMap会有一个特殊的标志对象:ForwardingNode…

如何接入sbus航模遥控器?

买了航模遥控器不会用sbus?快来快来我来教你呀(滑稽如何接入sbus航模遥控器? 最近队内大疆的遥控器短缺,故自行购买一款便宜好用的遥控器来替代,但是协议与dbus不同,研究了一阵子,所以诞生了这一篇文章来帮助大家少走弯路。 遥控器构成 一般都有发射端和接收端:发射端为…

2/15图论浅讲(知识点)

2/15图论浅讲(知识点) (后期会转移博客,所以排版不太好) 前置知识-vector 动态数组 操作1:创建一个动态数组 vector<数据类型> 数组名字操作2:插入元素 O(logn) 方式1:q.push_back(数据);在数组最后面塞数据 方式2:q.insert(q.begin()+i,a);i为下标,将a数据插入…

char**指针与const

1,char**char c = 0;char* p1 = &c; //p1是一个指针变量, 存放的是char类型变量的地址 *p1 = 1; const char* p2 = &c; //p1是一个指针变量, 存放的是char类型变量的地址, const修饰*, 表示指针内容(*p2)不可变char** p3; //p3是一个指针变量, 存放的是char*类型变量的…

升鲜宝供应链管理系统重构版发布(技术点:Java8、mysql8.0 uniapp、vue、android、web 框架: Vue3+Spring Boot3) ,界面功能t升级(四 )

升鲜宝供应链管理系统重构版发布(技术点:Java8、mysql8.0 uniapp、vue、android、web 框架: Vue3+Spring Boot3) ,界面功能t升级(四 ) 工作台 系统 商品 客户 门店 订单

(自适应手机端)英文外贸网站模板 日用百货网站源码下载

(自适应手机端)英文外贸网站模板 日用百货网站源码下载 PbootCMS内核开发的网站模板,该模板适用于外贸网站模板、日用百货网站源码等企业,当然其他行业也可以做,只需要把文字图片换成其他行业的即可; 自适应移动端,同一个后台,数据即时同步,简单适用!附带测试数据!友好…

Markdown 语法学习

Markdown 语法学习 标题: # + 三级标题 四级标题 字体 hello,world! hello,world! hello,world! hello,world! 引用选择狂神说Java>这是引用分割线图片超链接 博客园 - 开发者的网上家园) 列表A B CA B C表格名字 性别 生日张三 男 1997.1.1李斯 女 1995.7.6代码hello

一级倒立摆平衡控制系统MATLAB仿真,可显示倒立摆平衡动画,对比极点配置,线性二次型,PID,PI及PD五种算法

1.算法仿真效果 本课题是针对博主原来写的文章《基于MATLAB的一级倒立摆控制仿真,带GUI界面操作显示倒立摆动画,控制器控制输出》的升级。升级内容包括如下几个方面:增加了PI控制器,PD控制器,同时对极点配置,线性二次型,PID,PI及PD五种算法的控制输出曲线进行对比。matlab2…

使用Spring Initializr方式构建Spring Boot项目

按教材 下例选用IntelliJ IDEA 2024.3.3付费版 创建项目JDK版本根据实际情况。启动类简析 package com.example.demo; // 这段代码位于 com.example.demo 这个包下import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBo…