鉴于两场比赛 A 和 B ,限制条件是A可以在奇数分钟上进行,B只能在偶数分钟内进行。比如第一秒的比赛A然后是第三秒的比赛,同样是比赛。
现在好的序列被定义为:
(1)如果根据他们的规则进行比赛,即A将在奇数分钟上进行,B在偶数分钟上进行。
(2)A和B不是在整个序列中交替播放。
例如,
AXAXA:X表示在那一分钟没有比赛,良好的序列。
ABXXXB:顺序很好,因为两个都是根据规则进行的,然后是第一个A然后是B,然后是B.然后再次播放B.
XXXX:良好的序列。
ABXXAB:序列不好。
考虑到玩游戏的总分钟数,计算好序列的总数。由于数字可以非常大,因此提供了模数1000000007的答案。
我是通过创建每个字符串并检查其正确性来完成的。它是O(2 ^ n)。从1开始,我有更少的n作为2,3,5,9,18,38,82,177,379,803,...... n的答案。
我如何通过DP做到?
答案 0 :(得分:0)
此代码是否适合您,我添加了一个演示here。请看看
#include <iostream>
#include <cstdio>
using namespace std;
#define MOD 1000000007
int dp[100005][3][4]= {0};
int main() {
int n;
cin >> n;
dp[1][0][1] = 1;
dp[1][2][0] = 1;
for(int i=2; i<=n; i++){
if(i&1){
dp[i][2][0] = dp[i-1][2][0];
dp[i][0][1] = dp[i-1][2][0];
dp[i][2][1] = (dp[i-1][0][1] + dp[i-1][2][1]);
dp[i][1][3] = dp[i-1][1][3];
dp[i][2][2] = (dp[i-1][1][2] + dp[i-1][2][2])%MOD;
dp[i][0][3] = ((dp[i-1][1][2] + dp[i-1][2][2])%MOD + (dp[i-1][1][3] + dp[i-1][0][3])%MOD)%MOD;
}
else {
dp[i][2][0] = dp[i-1][2][0];
dp[i][1][2] = dp[i-1][2][0];
dp[i][2][1] = (dp[i-1][0][1] + dp[i-1][2][1]);
dp[i][1][3] = ((dp[i-1][0][1] + dp[i-1][2][1])%MOD + (dp[i-1][1][3] + dp[i-1][0][3])%MOD)%MOD;
dp[i][2][2] = (dp[i-1][1][2] + dp[i-1][2][2])%MOD;
dp[i][0][3] = dp[i-1][0][3];
}
// for(int j=0;j<=2;j++){
// for(int k=0;k<=3;k++){
// if(dp[i][j][k])
// printf("i=%d j=%d k=%d dp=%d\n",i,j,k,dp[i][j][k]);
// }
// }
}
int p = 1;
for(int i=1; i<=n; i++){
p = (p*2) % MOD;
}
p = (p - dp[n][0][3] - dp[n][1][3] )%MOD;
p = (p+MOD)%MOD;
cout << p << endl;
return 0;
}
答案 1 :(得分:0)
假设我们有州
所以你通过从小范围(长度1)到给定范围来解决,并在添加x或a,b时继续计算状态。
让我们看看长度
将a和x添加到空字符串
总计2
添加b和x
总计4
添加a和x
总计7
添加b和x
Total 13
添加和x
Total 22
复杂性将是O(n)
代码将很快添加