[hackerrank]Unique Divide And Conquer
2016-11-15 16:01
330 查看
题目大意
有多少种不同的n个节点的带编号无根树点分治过程唯一?DP
设f[i]表示i个节点时的答案。g[i]表示i个节点组成的森林,森林中每一个棵树都是点分治过程唯一的,而且是有根树,有多少种。
对于f的计算,首先重心有i种编号,然后思考除去重心后的森林部分,可以用g[i-1]表示除了该层外点分治过程唯一的方案,然后减去非法的情况。
非法情况包括:删去点不是重心,点分治过程不唯一。
两种情况可以合成一种:森林中存在一颗树的子树大小为j,且j>=(i+1)/2。(可以自己探究为什么是(i+1)/2,这里的除法当然是整除)
那么我们这个j,首先这棵树的点分治过程必须唯一,而且还要是有根树(对应g的方案),那么根的方案可以有j种选择(注意这里为什么不会算重,不一样的选根可能使得树的形态一致,但编号一定不一致。如果编号也一致,则原来一定算重了!)。同时我们要从i-1种编号中选j个组成这棵树,于是得到f的递推式。
f[i]=i∗(g[i−1]−∑i+12j=1f[j]∗j∗g[i−j−1]∗Cji−1)
再来考虑g如何递推。
为了不算重,我们思考如下过程:
每次删掉当前编号最小点所在的树。
那么一颗森林删除方法唯一。
因此枚举编号最小点所在的树大小j,这棵树点分治过程唯一且有根,同样是f[j]*j,其余是g[i-j],然后编号最小点一定在,因此我们要从i-1个编号选出j-1个编号给这颗树。
g[i]=∑ij=1f[j]∗j∗g[i−j]∗Cj−1i−1
递推f和g,f
就是答案。
#include<cstdio> #include<algorithm> #define fo(i,a,b) for(i=a;i<=b;i++) #define fd(i,a,b) for(i=a;i>=b;i--) using namespace std; typedef long long ll; const int maxn=3000+10; int f[maxn],g[maxn],fac[maxn],inv[maxn]; int i,j,k,l,t,n,mo; int quicksortmi(int x,int y){ if (!y) return 1; int t=quicksortmi(x,y/2); t=(ll)t*t%mo; if (y%2) t=(ll)t*x%mo; return t; } int C(int n,int m){ if (n<m) return 0; return (ll)fac *inv[m]%mo*inv[n-m]%mo; } int main(){ scanf("%d%d",&n,&mo); fac[0]=1; fo(i,1,n) fac[i]=(ll)fac[i-1]*i%mo; inv =quicksortmi(fac ,mo-2); fd(i,n-1,0) inv[i]=(ll)inv[i+1]*(i+1)%mo; g[0]=1; fo(i,1,n){ t=g[i-1]; fo(j,(i+1)/2,i-1) t=(t-(ll)f[j]*g[i-j-1]%mo*C(i-1,j)%mo*j%mo)%mo; f[i]=(ll)i*t%mo; fo(j,1,i) g[i]=(g[i]+(ll)g[i-j]*f[j]%mo*C(i-1,j-1)%mo*j%mo)%mo; } (f +=mo)%=mo; printf("%d\n",f ); }
相关文章推荐
- [HackerRank University CodeSprint]Unique Divide And Conquer
- 【HackerRank】Sherlock and Array
- 归并排序(mergeSort) 与 分而治之策略(divide and conquer)
- [hackerrank]John and GCD list
- Divide and Conquer
- 分治法——主定理(Divide and Conquer - The Master Theorem)
- Divide and Conquer -- Leetcode problem241:Different Ways to Add Parentheses
- [Leetcode刷题总结系列][Dynamic programming][Divide-and-conquer]53.Maximum Subarray
- Divide and conquer:Aggressive Cows(POJ 2456)
- LeetCode 53. Maximum Subarray--Divide and Conquer(分治法)
- Divide and conquer:Moo University - Financial Aid(POJ 2010)
- SGU 229 Divide and conquer(模拟)
- HackerRank "Shashank and List"
- Hackerrank Sherlock and The Beast
- 1.Two Sum (Array; Divide-and-Conquer)
- Divide and Conquer:241. Different Ways to Add Parentheses
- [hackerrank]Bob and Ben
- LeetCode之Divide and Conquer题目汇总
- selection problem-divide and conquer
- Divide and Conquer -- Leetcode problem240. Search a 2D Matrix II