luogu P4451 [国家集训队]整数的lqp拆分

https://www.luogu.com.cn/problem/P4451

首先分析一波
众所周知斐波那契数列生成函数为
F(x)=x1−x−x2\large F(x)=\frac{x}{1-x-x^2}F(x)=1xx2x
考虑把n拆分成i个数
显然答案为ANS=∑i=0F(x)i\large ANS = \sum\limits_{i=0} F(x)^iANS=i=0F(x)i
然后根据生成函数入门知识可得
ANS=11−F(x)=1−x−x21−2x−x2\large ANS = \frac{1}{1-F(x)}=\frac{1-x-x^2}{1-2x-x^2}ANS=1F(x)1=12xx21xx2
这个就是答案生成函数的封闭形式
先只考虑分子为111的情况,即11−2x−x2\large \frac{1}{1-2x-x^2}12xx21是什么意思

A(X)=2x+x2A(X)=2x+x^2A(X)=2x+x2
11−A(x)\large \frac{1}{1-A(x)}1A(x)1

这个东西逆推回去发现它的形式是
∑i=0A(x)i\large \sum\limits_{i=0}A(x)^ii=0A(x)i

考虑它的意义
就是

草不会,忘了
wdnmd

### 题目解析 洛谷 P1645 序列问题描述为给定若干个区间,每个区间有对应的整数数量要求,需要在满足这些区间内整数数量要求的情况下,求出最少需要选择多少个整数。该问题可以使用差分约束系统来解决。差分约束系统是一种特殊的不等式组,通过将问题转化为图的最短路问题来求解。对于每个区间 `[x, y]` 要求至少有 `z` 个整数,可转化为不等式 `s[y] - s[x - 1] >= z`,其中 `s[i]` 表示从 `1` 到 `i` 选择的整数数量。同时,还有隐含条件 `0 <= s[i] - s[i - 1] <= 1`,表示每个位置最多选一个整数,最少不选。 ### 解题思路 1. **构建图**:将不等式转化为图的边。对于 `s[y] - s[x - 1] >= z`,可变形为 `s[x - 1] <= s[y] - z`,对应图中从 `y` 到 `x - 1` 有一条权值为 `-z` 的边;对于 `s[i] - s[i - 1] >= 0` 变形为 `s[i - 1] <= s[i]`,对应图中从 `i` 到 `i - 1` 有一条权值为 `0` 的边;对于 `s[i] - s[i - 1] <= 1` 变形为 `s[i] <= s[i - 1] + 1`,对应图中从 `i - 1` 到 `i` 有一条权值为 `1` 的边。 2. **求解最短路**:使用最短路算法(如 SPFA 算法)求解图的最短路。从一个源点开始,不断更新各点的最短距离。 3. **得出结果**:最终 `s[最大位置]` 即为满足所有区间要求的最少整数数量。 ### 代码实现 ```cpp #include <cstdio> #include <iostream> using namespace std; const int maxn = 100010; int head[maxn], nnext[maxn], to[maxn], team[maxn], length[maxn]; int n; int tot, s = 0, t = 0; int dis[maxn]; bool b[maxn]; void add(int x, int y, int l) { tot++; nnext[tot] = head[x]; head[x] = tot; to[tot] = y; length[tot] = l; } int main() { scanf("%d", &n); for (int i = 0; i <= 1000; i++) { add(i, i - 1, -1); add(i - 1, i, 0); } for (int i = 1; i <= n; i++) { int x, y, z; cin >> x >> y >> z; add(x - 1, y, z); } for (int i = 0; i <= 1000; i++) { dis[i] = -1e9; } dis[0] = 0; team[t] = 0; t++; b[0] = true; while (s != t) { int now = team[s]; s++; b[now] = false; for (int i = head[now]; i; i = nnext[i]) { int y = to[i]; if (dis[y] < dis[now] + length[i]) { dis[y] = dis[now] + length[i]; if (!b[y]) { team[t] = y; t++; b[y] = true; } } } } cout << dis[1000]; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值