Q~ 抛一枚硬币 n 次,每次可能是正面或者反面向上,求没有连续超过 k 次硬币向上的方案数
A :
dp[ i ] 表示到 i 位置的方案数,
1 . 当 i < k 时, dp[i] = dp[i-1]*2
2 . 当 i = k 时, dp[i] = dp[i-1]*2 - 1
3. 当 i > k 时, dp[i] = dp[i-1]*2 - dp[i-k-1]
ll n, k;
ll dp[maxn];void solve() {dp[0] = 1;ll res = 1;for(ll i = 1; i <= n; i++){if (i < k) dp[i] = dp[i-1]*2;else if (i == k) dp[i] = dp[i-1]*2-1;else dp[i] = dp[i-1]*2-dp[i-k-1];dp[i] %= mod;res *= 2; res %= mod;}ll ans = (res-dp[n]+mod)%mod;printf("%lld\n", ans);
}
Q~ 有三种字母, 一个长度为 n 的序列的每一个位置只可能是这三种字母,但要求连续的三个位置不能同时出现这三种,求方案数
A :
dp[i][0] 表示 i 位置与 i-1 位置相同的方案数, dp[i][1] 表示 i 位置与 i-1 位置不同的方案数
dp[i][0] = dp[i-1][0] + dp[i-1][1]
dp[i][1] = 2*dp[i-1][0] + dp[i-1][1]
void solve() {dp[1][0]=3;dp[1][1]=0;for(int i=2;i <= n; i++){dp[i][0]=dp[i-1][0]+dp[i-1][1];dp[i][1]=2*dp[i-1][0]+dp[i-1][1];}
}