线性dp-计数类题目9(斐波那契字符串)

题目链接

解题思路

题目中的字符串有0和1组成,要构成逆序对,1要在0前面。

根据题意:

  • S 1 = 0 S1=0 S1=0
  • S 2 = 0 S2=0 S2=0
  • 对于任意正整数 n ( n ≥ 3 ) , S n = S n − 2 + S n − 1 n(n≥3),Sn=Sn−2+Sn−1 n(n≥3),Sn=Sn−2+Sn−1(" + + +"表示字符串拼接)。

如果我们知道 S n − 2 Sn-2 Sn−2和 S n − 1 Sn-1 Sn−1中的分别有多少个逆序对,有知道 S n − 2 Sn-2 Sn−2中有多少个1, S n − 1 Sn-1 Sn−1中有多少个0,那么我们就可以知道 S n Sn Sn中有多少个逆序对。

于是我们定义 d p i 0 dpi0 dpi0表示 S i Si Si中0的个数, d p i 1 dpi1 dpi1表示 S i Si Si中1的个数。再定义 f i fi fi为 S i Si Si的逆序对个数,我们可以得到以下状态转移方程:

i = 1 , d p i 0 = 1 , d p i 1 = 0 , f i = 0 i=1,dpi0=1,dpi1=0,fi=0 i=1,dpi0=1,dpi1=0,fi=0

i = 2 , d p i 0 = 0 , d p i 1 = 1 , f i = 0 i=2,dpi0=0,dpi1=1,fi=0 i=2,dpi0=0,dpi1=1,fi=0

i > = 3 时 , d p i 0 = d p i − 2 0 + d p i − 1 0 , d p i 1 = d p i − 2 1 + d p i − 1 1 , f i = f i − 2 + f i − 1 + d p i − 2 1 ∗ d p i − 1 0 . i>=3时,dpi0=dpi-20+dpi-10,dpi1=dpi-21+dpi-11,fi=fi-2+fi-1+dpi-21*dpi-10. i>=3时,dpi0=dpi−20+dpi−10,dpi1=dpi−21+dpi−11,fi=fi−2+fi−1+dpi−21∗dpi−10.

(注意:要对结果取模)

AC代码

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1e9 + 7, maxn = 1e5 + 5;
int t, dp[maxn][2], f[maxn], n;
void init() {
	dp[1][0] = 1;
	dp[2][1] = 1;
	for (int i = 3; i <= 100000; i++) {
		dp[i][0] = (dp[i - 1][0] + dp[i - 2][0]) % mod;
		dp[i][1] = (dp[i - 1][1] + dp[i - 2][1]) % mod;
		f[i] = (dp[i - 1][0] * dp[i - 2][1] % mod + f[i - 1] + f[i - 2]) % mod;
	}
}
signed main() {
	cin >> t;
	init();
	while (t--) {
		cin >> n;
		cout << f[n] << endl;
	}
	return 0;
}
相关推荐
菜菜的顾清寒1 小时前
力扣HOT100(49)动态规划 -- 打家劫舍
算法·leetcode·动态规划
葡萄城技术团队1 小时前
观察生活:人是如何分词的
算法·生活
装不满的克莱因瓶1 小时前
什么是特征分解?从数学定义到现实问题的映射
人工智能·数学·算法·机器学习·ai·特征分解
killerbasd1 小时前
总结 6.1
算法
「維他檸檬茶」1 小时前
大模型算法学习2026.6.1
学习·算法·大模型·nlp
玖釉-1 小时前
LeetCode Hot 100 知识点总结与算法指南
c++·windows·算法·leetcode
填满你的记忆1 小时前
《动态规划-基础篇》
算法·动态规划·力扣
进击的荆棘1 小时前
优选算法——队列+宽搜
数据结构·c++·算法·leetcode·bfs·队列
黎阳之光1 小时前
虚实同源·数智治水:黎阳之光视频孪生,重构智慧水务新范式
运维·物联网·算法·安全·数字孪生