今年光棍不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;
}