2 条题解
-
1
/* * 字符序列 (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
/* * 字符序列 (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
- 上传者