好的游戏序列

时间:2017-08-13 17:16:20

标签: algorithm dynamic-programming

鉴于两场比赛 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做到?

2 个答案:

答案 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,xx, - 当添加b时,它导致状态2,当它导致3时,当x没有状态变化时
  2. xb,xbxbx, - 当x没有状态变化时,b状态没有变化,当它导致状态5时
  3. a,axa, - 当x没有状态变化时,当状态没有变化时,当b导致状态4时
  4. ab,xxab,abx - x状态没有变化,因为b变为状态2,应该忽略添加
  5. xba,xbax - x状态没有变化,因为它变为3,对于b我们应该忽略添加b
  6. 所以你通过从小范围(长度1)到给定范围来解决,并在添加x或a,b时继续计算状态。

    让我们看看长度

    1. 将a和x添加到空字符串

      • State1 - 0 + 1(x)
      • State2 - 0
      • State3 - 0 + 1(a)
      • State4 - 0
      • State5 - 0

      总计2

    2. 添加b和x

      • State1 - 1
      • State2 - 0 + 1(来自state1,加上b)
      • State3 - 1
      • State4 - 0 + 1(来自state3,加上b)
      • State5 - 0

      总计4

    3. 添加a和x

      • State1 - 1
      • State2 - 1
      • State3 - 1 + 1(来自state1,加上一个)+ 1(来自state3本身的axa ..)
      • State4 - 1
      • State5 - 0 + 1(通过添加一个来自stat2)

      总计7

    4. 添加b和x

      • State1 - 1
      • State2 - 1 + 1(来自状态1)+ 1(来自state2本身)+ 1(来自state4)
      • State3 - 3
      • State4 - 1 + 3(来自state3)
      • State5 - 1

      Total 13

    5. 添加和x

      • State1 - 1
      • State2 - 4
      • State3 - 3 + 1(来自state1)+ 3(来自state3本身)+ 1(来自state5)
      • State4 - 4
      • State5 - 1 + 4(来自state2)

      Total 22

    6. 复杂性将是O(n)

      代码将很快添加