2 条题解

  • 1
    @ 2026-9-13 13:30:16
    
    /*
     * 字符序列 (temege.com 1301)
     *
     * 题意: 从 {A,B,C} 中取 n 个字符组成序列, 任意两个"相邻的字"的子序列不能相同,
     *       即不允许存在相邻的两个长度为 2 的子串相等
     *       <=> 序列中不出现形如 xyxy 的连续 4 个字符 (含 x==y, 如 aaaa 也禁止)
     *       <=> 不存在 i 使 s[i]==s[i+2] 且 s[i+1]==s[i+3]
     *
     * 例: N=5 时 ABCBA 合法; ABCBC 含 BC|BC, ABABC 含 AB|AB, 故非法。与样例一致。
     *
     * 解法: DP, 状态 = 序列最后 3 个字符, 共 3^3 = 27 种。
     *       追加字符 d 时, 若 a==c 且 b==d 则出现 xyxy, 禁止。
     * 复杂度: O(n * 27 * 3), 空间 O(27)
     */
    
    int main() {
        int n;
        scanf("%d", &n);
    
        if (n == 1) { printf("3\n"); return 0; }
        if (n == 2) { printf("9\n"); return 0; }
    
        long long dp[27], ndp[27];
        for (int s = 0; s < 27; ++s) dp[s] = 1;   // 长度 3 的所有序列均合法
    
        for (int i = 3; i < n; ++i) {
            for (int s = 0; s < 27; ++s) ndp[s] = 0;
            for (int a = 0; a < 3; ++a)
                for (int b = 0; b < 3; ++b)
                    for (int c = 0; c < 3; ++c) {
                        long long v = dp[a * 9 + b * 3 + c];
                        if (!v) continue;
                        for (int d = 0; d < 3; ++d) {
                            if (a == c && b == d) continue;   // 出现 xyxy, 剪掉
                            ndp[b * 9 + c * 3 + d] += v;
                        }
                    }
            for (int s = 0; s < 27; ++s) dp[s] = ndp[s];
        }
    
        long long ans = 0;
        for (int s = 0; s < 27; ++s) ans += dp[s];
        printf("%lld\n", ans);
        return 0;
    }
    
    
    • 1
      @ 2026-9-13 13:29:45
      
      /*
       * 字符序列 (temege.com 1301)
       *
       * 题意: 从 {A,B,C} 中取 n 个字符组成序列, 任意两个"相邻的字"的子序列不能相同,
       *       即不允许存在相邻的两个长度为 2 的子串相等
       *       <=> 序列中不出现形如 xyxy 的连续 4 个字符 (含 x==y, 如 aaaa 也禁止)
       *       <=> 不存在 i 使 s[i]==s[i+2] 且 s[i+1]==s[i+3]
       *
       * 例: N=5 时 ABCBA 合法; ABCBC 含 BC|BC, ABABC 含 AB|AB, 故非法。与样例一致。
       *
       * 解法: DP, 状态 = 序列最后 3 个字符, 共 3^3 = 27 种。
       *       追加字符 d 时, 若 a==c 且 b==d 则出现 xyxy, 禁止。
       * 复杂度: O(n * 27 * 3), 空间 O(27)
       */
      
      int main() {
          int n;
          scanf("%d", &n);
      
          if (n == 1) { printf("3\n"); return 0; }
          if (n == 2) { printf("9\n"); return 0; }
      
          long long dp[27], ndp[27];
          for (int s = 0; s < 27; ++s) dp[s] = 1;   // 长度 3 的所有序列均合法
      
          for (int i = 3; i < n; ++i) {
              for (int s = 0; s < 27; ++s) ndp[s] = 0;
              for (int a = 0; a < 3; ++a)
                  for (int b = 0; b < 3; ++b)
                      for (int c = 0; c < 3; ++c) {
                          long long v = dp[a * 9 + b * 3 + c];
                          if (!v) continue;
                          for (int d = 0; d < 3; ++d) {
                              if (a == c && b == d) continue;   // 出现 xyxy, 剪掉
                              ndp[b * 9 + c * 3 + d] += v;
                          }
                      }
              for (int s = 0; s < 27; ++s) dp[s] = ndp[s];
          }
      
          long long ans = 0;
          for (int s = 0; s < 27; ++s) ans += dp[s];
          printf("%lld\n", ans);
          return 0;
      }
      
      
      
      • 1

      信息

      ID
      1301
      时间
      1000ms
      内存
      256MiB
      难度
      10
      标签
      递交数
      7
      已通过
      2
      上传者