1 条题解
-
0
自动搬运
来自洛谷,原作者为

AmamiyaUmi
**搬运于
2025-08-24 21:55:38,当前版本为作者最后更新于2017-12-23 23:42:22,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
咸鱼的blog:http://www.neptuuz.com/wordpress/?p=237
经典的环形dp,枚举开头,对结尾的状态要与开头判断一下是否合法
dp[i][j]表示第i个顶点染颜色j的方案数,可以得到
dp[i][j] = ∑dp[i-1][k] (颜色j可以被染上 && i和i-1被改变边属性时:j=k;否则j != k)
复杂度O(nc^3)
然后这题坑的地方是2操作对于同一顶点有多个,也就是说对于一个顶点可能不能染多种颜色(卡了两个点不然AK了QAQ)
#include<stdio.h> #include<iostream> #include<string.h> #define MAXN 50010 #define MOD 987654321 using namespace std; int n, m, c, uncol[MAXN][15], e[MAXN], dp[MAXN][15], ans; int main() { scanf("%d%d%d", &n, &m, &c); for (int i = 1, opt, x, y; i <= m; ++i) { scanf("%d%d%d", &opt, &x, &y); if (opt == 1) { for (int j = 1; j <= c; ++j) { if (j != y) uncol[x][j] = 1; } } else if (opt == 2) { uncol[x][y] = 1; } else { if (x > y) swap(x, y); e[y] = x; } } for (int p = 1; p <= c; ++p) { if (uncol[1][p]) continue; memset(dp, 0, sizeof(dp)); dp[1][p] = 1; for (int i = 2; i < n; ++i) { for (int j = 1; j <= c; ++j) { if (uncol[i][j]) continue; if (e[i]) { dp[i][j] += dp[i-1][j]; dp[i][j] %= MOD; } else for (int k = 1; k <= c; ++k) { if (j == k) continue; dp[i][j] += dp[i-1][k]; dp[i][j] %= MOD; } } } for (int i = 1; i <= c; ++i) { if (uncol[n][i] || i == p) continue; if (e[n]) { dp[n][i] += dp[n-1][i]; dp[n][i] %= MOD; } else for (int j = 1; j <= c; ++j) { if (i == j) continue; dp[n][i] += dp[n-1][j]; dp[n][i] %= MOD; } } for (int i = 1; i <= c; ++i) { ans += dp[n][i]; ans %= MOD; } } printf("%d\n", ans); return 0; }```
- 1
信息
- ID
- 2932
- 时间
- 2000ms
- 内存
- 250MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者