PC快脱单了

题目链接

今年光棍不11

单身的Pc最讨厌的就是11月11日就是 我们所说的光棍节.

他不想看到所有 '11' 的存在,如果存在,pc就会很伤心

有天小学弟给了Pc 一个长度n的01串,小学弟并不想让Pc伤心。

现在你要帮小学弟求出有多少种长度为n且让pc不会伤心的01串 (数量可能很大,所以最后的结果对1e9 + 7取模)。

输入描述:

一个整数 1 ≤ n ≤ 1e6

输出描述:

一个整数,表示结果.

题解:

数位dp题,好久没写了,有点生疏,dp数组的定义在代码中有注释,不讲了吧

#include <bits/stdc++.h>
#define DEBUG puts("------------")
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
ll dp[N][3];
const int mod = 1e9 + 7;
ll qpow(ll a, ll b) {
	ll res = 1;
	while (b) {
		if (b & 1) {
			res = res * a % mod;
		}
		b >>= 1;
		a = a * a % mod;
	}
	return res % mod;
}
int main()
{
#ifdef DEBUG
	ios::sync_with_stdio(0);
#endif // DEBUG
	//数位DP
	//dp[i][0]:长度为i末尾已经有连续0个1 并且不含有两个连续的1
	//dp[i][1]:长度为i末尾已经有连续1个1 并且不含有两个连续的1
	//dp[i][2]:长度为i有两个1
	//转移:dp[i][0] 可以有dp[i-1][0]和dp[i-1][1]末尾加一个0
	//dp[i][1]可以由dp[i-1][0]末尾加一个1
	//dp[i][2]就是dp[i-1][2]后面随便加0或者1,也就是dp[i-1][2] * 2以及dp[i-1][1]加一个1
	dp[1][0] = 1;
	dp[1][1] = 1;
	dp[1][2] = 0;
	for (int i = 2; i <= 1000000; i++) {
		dp[i][0] = dp[i - 1][0] + dp[i - 1][1];
		dp[i][1] = dp[i - 1][0];
		dp[i][2] = dp[i - 1][2] * 2 + dp[i - 1][1];
		dp[i][0] %= mod;
		dp[i][1] %= mod;
		dp[i][2] %= mod;
	}
	int n;
	cin >> n;
	ll res = qpow(2, n);
	res -= dp[n][2];
	res = (res + mod) % mod;
	cout << res << "\n";
	return 0;
}
发布了143 篇原创文章 · 获赞 11 · 访问量 8204

猜你喜欢

转载自blog.csdn.net/weixin_43701790/article/details/103549812
今日推荐