lightoj 1382 - The Queue(树形dp)
Posted Gealo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了lightoj 1382 - The Queue(树形dp)相关的知识,希望对你有一定的参考价值。
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1382
题解:简单的树形dp加上组合数学。
#include <iostream> #include <cstring> #include <cstdio> #include <vector> #define mod 1000000007 using namespace std; typedef long long ll; const int M = 1234; ll dp[M] , C[M][M]; int fa[M] , num[M]; vector<int> vc[M]; void find_num(int u , int pre) { num[u] = 1; int len = vc[u].size(); for(int i = 0 ; i < len ; i++) { int v = vc[u][i]; if(v == pre) continue; find_num(v , u); num[u] += num[v]; } } void dfs(int u , int pre) { int len = vc[u].size(); ll ans = 1 , sum = num[u]; for(int i = 0 ; i < len ; i++) { int v = vc[u][i]; if(v == pre) continue; dfs(v , u); ans *= (C[sum - 1][num[v]] * dp[v]) % mod; ans %= mod; sum -= num[v]; } dp[u] = ans; dp[u] %= mod; } int main() { int t , n; int Case = 0; scanf("%d" , &t); C[0][0] = 1; for(int i = 1 ; i <= M - 1 ; 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; } while(t--) { scanf("%d" , &n); for(int i = 1 ; i <= n ; i++) { vc[i].clear(); dp[i] = 1; fa[i] = -1; num[i] = 0; } for(int i = 0 ; i < n - 1 ; i++) { int u , v; scanf("%d%d" , &u , &v); vc[u].push_back(v); fa[v] = u; } int root = 1; for(int i = 1 ; i <= n ; i++) { if(fa[i] == -1) { root = i; break; } } find_num(root , -1); dfs(root , -1); printf("Case %d: %lld\n" , ++Case , dp[root] % mod); } return 0; }
以上是关于lightoj 1382 - The Queue(树形dp)的主要内容,如果未能解决你的问题,请参考以下文章
LightOJ - 1095 - Arrange the Numbers(错排)
LightOJ - 1173 - The Vindictive Coachf(DP)
LightOJ 1342 Aladdin and the Magical Sticks [想法题]
Lightoj 1025 - The Specials Menu