【GDSOI2017第二轮模拟】树
2017-04-18 12:24
435 查看
*Description
n个点,它们从1到n进行标号,第i个点的限制为度数不能超过A[i].现在对于每个s (1 <= s <= n),问从这n个点中选出一些点组成大小为s的有标号无根树的方案数。
Solution
这题一眼就是prufer序列,但是比赛的时候忘记了prufer序列的性质了。prufer序列就是每个数的出现次数不会超过这个点的度数,那么直接一个DP:
f[i][j][k]表示做到第i个数,选了j个节点,序列中有k个然后用组合数直接DP
Code
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; typedef long long ll; const int maxn=107,mo=1004535809; ll i,j,k,l,t,n,m,ans; ll a[maxn],f[maxn][maxn][maxn]; ll c[maxn][maxn],fact[maxn]; int main(){ freopen("tree.in","r",stdin); freopen("tree.out","w",stdout); fact[0]=1;fo(i,1,100)c[i][0]=c[0][i]=1,fact[i]=fact[i-1]*i; fo(i,1,100)fo(j,1,i)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mo;c[0][0]=1; scanf("%d",&n); fo(i,1,n)scanf("%d",&a[i]); f[0][0][0]=1; fo(i,1,n){ fo(j,0,n){ fo(k,0,n-2){ f[i][j][k]=f[i-1][j][k]; if(!j)continue; fo(l,0,min(k,a[i]-1)){ f[i][j][k]=(f[i-1][j-1][k-l]*c[k][l]%mo+f[i][j][k])%mo; } } } } printf("%lld ",n); fo(i,2,n)printf("%lld ",f [i][i-2]); }
相关文章推荐
- 【jzoj5068】【GDSOI2017第二轮模拟】【树】【动态规划】
- 【GDSOI2017第二轮模拟】树
- 【jzoj5071】【GDSOI2017第二轮模拟】【奶酪】【树形动态规划】
- 【JZOJ5068】【GDSOI2017第二轮模拟】树
- 【JZOJ5069】【GDSOI2017第二轮模拟】蛋糕
- JZOJ 5068. 【GDSOI2017第二轮模拟】树
- 【jzoj5069】【GDSOI2017第二轮模拟】【蛋糕】【莫比乌斯反演】【杜教筛】
- 【GDSOI2017模拟4.13】炮塔 最小割
- 【jzoj5081】【GDSOI2017第三轮模拟】【Travel Plan】【动态规划】
- 【GDSOI2017第三轮模拟】Informatics Training(码农,平衡树)
- 【JZOJ5056】【GDSOI2017模拟4.13】黑白广场
- 【GDSOI2017模拟】Travel Plan
- 【JZOJ5057】【GDSOI2017模拟4.13】炮塔
- 【JZOJ5065】【GDOI2017第二轮模拟day2】开房间
- [JZOJ5081]. 【GDSOI2017第三轮模拟】Travel Plan
- 【jzoj5060】【GDOI2017第二轮模拟day1】【公路建设】【数据结构】
- 【JZOJ5066】【GDOI2017第二轮模拟day2】中位数
- 【GDOI2017第二轮模拟day1】公路建设(克鲁斯卡尔最小生成树+线段树+归并)
- 【JZOJ5058】【GDSOI2017模拟4.13】采蘑菇
- [JZOJ5083].【GDSOI2017第三轮模拟】Gift