题解:AT_arc130_d [ARC130D] Zigzag Tree
题意:很简单了,不再赘述。
做法:
首先注意到对于相邻两个点,他们不能同时是极大点和极小点,考虑将这个设进状态。
因为是排列,所以很自然考虑经典 dp,设 \(dp_{i,j,0/1}\) 代表节点 \(i\),在子树中排名为 \(j\),是一个极大点 / 极小点。
枚举 \(v\) 中有多少个点插在 \(u\) 前面,有转移式:
\[dp_{u,i+j, 0}=C_{i+j-1}^jC_{sz_u-i + sz_v-j}^{sz_u-i}dp_{u,i,0}\sum_{t\le j}dp_{v, t, 1}
\]
\[dp_{u,i+j, 1}=C_{i+j-1}^jC_{sz_u-i + sz_v-j}^{sz_u-i}dp_{u,i,1}\sum_{t\ge j + 1}dp_{v, t, 0}
\]
对后面的提前计算前缀和转移即可。
代码实现因为是一年前写得,所以可能和上述转移式不同,大体相同。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 3e3 + 5, mod = 998244353;
int C[maxn][maxn], n;
vector<int> e[maxn];
void prepare(int n) {
C[0][0] = 1;
for (int i = 1; i <= n; i++) {
C[i][0] = 1;
for (int j = 1; j <= i; j++)
C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod;
}
}
int dp[maxn][maxn][2], sz[maxn], pre[maxn], suf[maxn], g[maxn][2];
void dfs(int u, int fa) {
dp[u][1][0] = dp[u][1][1] = 1;
sz[u] = 1;
for (int i = 0; i < e[u].size(); i++) {
int v = e[u][i];
if(v == fa)
continue;
dfs(v, u);
for (int j = 0; j <= sz[v] + 1; j++)
pre[j] = suf[j] = 0;
for (int j = 1; j <= sz[v]; j++)
pre[j] = pre[j - 1] + dp[v][j][0], pre[j] %= mod;
for (int j = sz[v]; j >= 1; j--)
suf[j] = suf[j + 1] + dp[v][j][1], suf[j] %= mod;
for (int j = 1; j <= sz[u]; j++)
for (int k = 0; k <= sz[v]; k++) {
g[j + k][1] = (g[j + k][1] + dp[u][j][1] * C[j + k - 1][k] % mod * C[sz[v] - k + sz[u] - j][sz[v] - k] % mod * pre[k] % mod) % mod;
g[j + k][0] = (g[j + k][0] + dp[u][j][0] * C[j + k - 1][k] % mod * C[sz[v] - k + sz[u] - j][sz[v] - k] % mod * suf[k + 1] % mod) % mod;
}
sz[u] += sz[v];
for (int j = 0; j <= sz[u]; j++)
dp[u][j][0] = g[j][0], dp[u][j][1] = g[j][1], g[j][0] = g[j][1] = 0;
}
// for (int i = 1; i <= sz[u]; i++)
// cout << dp[u][i][0] << " " << dp[u][i][1] << endl;
// cout << endl;
}
signed main() {
cin >> n;
prepare(n + 1);
for (int i = 1; i < n; i++) {
int x, y;
cin >> x >> y;
e[x].push_back(y);
e[y].push_back(x);
}
dfs(1, 0);
int ans = 0;
for (int i = 1; i <= n; i++)
ans = (ans + dp[1][i][0] + dp[1][i][1]) % mod;
cout << ans << endl;
return 0;
}

浙公网安备 33010602011771号