题面

我编不下去了!

给出

n

n

n 个点,第

i

i

i 个点的度数限制为

a

i

a_i

ai​,现在需要选出

x

x

x 个点构成一颗树,要求这

x

x

x 个点中每个点的度数不超过这个点的

a

i

a_i

ai​ 值,求

x

=

1

,

2

,

,

n

x=1,2,\ldots,n

x=1,2,…,n 时的方案数。

两种方案不同,当且仅当选出的点集不同或者连边的方式不同。

输入格式

第一行一个正整数

T

T

T,代表有

T

T

T 组数据。每组数据第一行一个正整数

n

n

n

第二行

n

n

n 个正整数

a

1

,

a

2

,

,

a

n

a_1,a_2,\ldots,a_n

a1​,a2​,…,an​。

输出格式

对于每组数据,输出一行

n

n

n 个数,表示

x

=

1

,

2

,

,

n

x=1,2,\ldots,n

x=1,2,…,n 时的答案对

1000000007

1000000007

1000000007 取模后的结果。

样例输入

1
3
2 2 1

样例输出

3 3 2

数据范围与提示

本题共

10

10

10 组测试点。

对于第

i

i

i 个测试点,

1

n

5

i

,

1

T

10

,

1

a

1

,

a

2

,

,

a

n

n

1\leq n\leq 5i,1\leq T\leq 10,1\leq a_1,a_2,\ldots,a_n\leq n

1≤n≤5i,1≤T≤10,1≤a1​,a2​,…,an​≤n。

总的来说,

1

n

50

1\leq n\leq 50

1≤n≤50。

题解

根据 p

r

u

f

e

r

\rm prufer

prufer 序列的知识,我们可以发现,当

x

=

k

x=k

x=k,选的点集为

{

p

1

,

p

2

,

,

p

k

}

\{p_1,p_2,\ldots,p_k\}

{p1​,p2​,…,pk​} 时,答案为:

i

1

=

1

a

p

1

i

2

=

1

a

p

2

.

.

.

i

k

=

1

a

p

k

(

k

2

)

!

(

i

1

1

)

!

(

i

2

1

)

!

.

.

.

(

i

k

1

)

!

[

i

=

(

k

1

)

2

]

\sum_{i_1=1}^{a_{p_1}}\sum_{i_2=1}^{a_{p_2}}...\sum_{i_k=1}^{a_{p_k}}\frac{(k-2)!}{(i_1-1)!(i_2-1)!...(i_k-1)!}[\sum i=(k-1)*2]

i1​=1∑ap1​​​i2​=1∑ap2​​​...ik​=1∑apk​​​(i1​−1)!(i2​−1)!...(ik​−1)!(k−2)!​[∑i=(k−1)∗2]

看来思路已经很清晰了,但是现在暴力能拿

10

10

10 分吗?不好说。

考虑把这个式子拆开:

(

k

2

)

!

i

1

=

1

a

p

1

i

2

=

1

a

p

2

.

.

.

i

k

=

1

a

p

k

1

(

i

1

1

)

!

(

i

2

1

)

!

.

.

.

(

i

k

1

)

!

[

i

=

(

k

1

)

2

]

(k-2)!\sum_{i_1=1}^{a_{p_1}}\sum_{i_2=1}^{a_{p_2}}...\sum_{i_k=1}^{a_{p_k}}\frac{1}{(i_1-1)!(i_2-1)!...(i_k-1)!}[\sum i=(k-1)*2]

(k−2)!i1​=1∑ap1​​​i2​=1∑ap2​​​...ik​=1∑apk​​​(i1​−1)!(i2​−1)!...(ik​−1)!1​[∑i=(k−1)∗2]

右边那个大分式似乎有些头绪了?这不就相当于 "

k

k

k 个物品,每个物品有

a

p

i

a_{p_i}

api​​ 种,选

x

x

x 个的权值为

1

(

x

1

)

!

\frac{1}{(x-1)!}

(x−1)!1​ ,背包大小为

(

k

1

)

2

(k-1)*2

(k−1)∗2 ,问刚好塞满时每种情况权值积的和 "

所以就是个裸的背包DP了,令

d

p

[

i

]

[

j

]

dp[i][j]

dp[i][j] 为选了

i

i

i 物品,背包已用空间为

j

j

j 时的权值积的和,那么类似分组背包问题求解就完了。最终

x

=

k

x=k

x=k 时的答案就是

(

k

2

)

!

d

p

[

k

]

[

(

k

1

)

2

]

(k-2)!*dp[k][(k-1)*2]

(k−2)!∗dp[k][(k−1)∗2],复杂度

O

(

T

n

4

)

O(Tn^4)

O(Tn4) 。

CODE

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 55
#define LL long long
#define DB double
#define ENDL putchar('\n')
#define lowbit(x) (-(x) & (x))
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f=-f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
const int MOD = 1000000007;
int n,m,i,j,s,o,k;
inline void MD(int &x) {if(x>=MOD)x-=MOD;}
int a[MAXN];
int dp[MAXN][MAXN<<1];
int fac[MAXN],inv[MAXN],invf[MAXN];
int main() {
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
int T = read();
fac[1] = fac[0] = inv[1] = inv[0] = invf[1] = invf[0] = 1;
for(int i = 2;i <= 50;i ++) {
fac[i] = fac[i-1] *1ll* i % MOD;
inv[i] = (MOD-inv[MOD % i]) *1ll* (MOD/i) % MOD;
invf[i] = invf[i-1] *1ll* inv[i] % MOD;
}
while(T --) {
n = read();
for(int i = 1;i <= n;i ++) a[i] = read();
memset(dp,0,sizeof(dp));
dp[0][0] = 1;
int du = (n-1)*2;
for(int i = 1;i <= n;i ++) {
for(int ct = n;ct > 0;ct --) {
for(int j = du;j >= 1;j --) {
for(int x = 1;x <= j && x <= a[i];x ++) {
MD(dp[ct][j] += dp[ct-1][j-x] *1ll* invf[x-1] % MOD);
}
}
}
}
for(int k = 1;k <= n;k ++) {
if(k == 1) {printf("%d ",n);continue;}
if(k == 2) {printf("%lld ",n*1ll*(n-1) % MOD *1ll* inv[2] % MOD);continue;}
int ans = dp[k][(k-1)*2] *1ll* fac[k-2] % MOD;
printf("%d ",ans);
}
ENDL;
}
return 0;
}

[2021.4.9多校省选模拟35]隐形斗篷 (prufer序列,背包DP)的更多相关文章

  1. codehunter 「Adera 6」杯省选模拟赛 网络升级 【树形dp】

    直接抄ppt好了--来自lyd 注意只用对根判断是否哟留下儿子 #include<iostream> #include<cstdio> using namespace std; ...

  2. 6.29 省选模拟赛 坏题 AC自动机 dp 图论

    考场上随手构造了一组数据把自己卡掉了 然后一直都是掉线状态了. 最后发现这个东西不是subtask -1的情况不多 所以就没管无解直接莽 写题有点晚 故没调出来.. 考虑怎么做 容易想到建立AC自动机 ...

  3. 5.13 省选模拟赛 优雅的绽放吧,墨染樱花 多项式 prufer序列 计数 dp

    LINK:优雅的绽放吧,墨染樱花 当时考完只会50分的做法 最近做了某道题受到启发 故会做这道题目了.(末尾附30分 50分 100分code 看到度数容易想到prufer序列 考虑dp统计方案数. ...

  4. 5.4 省选模拟赛 修改 线段树优化dp 线段树上二分

    LINK:修改 题面就不放了 大致说一下做法.不愧是dls出的题 以前没见过这种类型的 不过还是自己dp的时候写丑了. 从这道题中得到一个结论 dp方程要写的优美一点 不过写的过丑 优化都优化不了. ...

  5. 3.29省选模拟赛 除法与取模 dp+组合计数

    LINK:除法与取模 鬼题.不过50分很好写.考虑不带除法的时候 其实是一个dp的组合计数. 考虑带除法的时候需要状压一下除法操作. 因为除法操作是不受x的大小影响的 所以要状压这个除法操作. 直接采 ...

  6. [CSP-S模拟测试]:简单的序列(DP)

    题目描述 从前有个括号序列$s$,满足$|s|=m$.你需要统计括号序列对$(p,q)$的数量. 其中$(p,q)$满足$|p|+|s|+|q|=n$,且$p+s+q$是一个合法的括号序列. 输入格式 ...

  7. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  8. 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)

    一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...

  9. 6.28 NOI模拟赛 好题 状压dp 随机化

    算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...

随机推荐

  1. JZOJ5384. 【NOIP2017提高A组模拟9.23】四维世界

    题目 Description 众所周知,我们常感受的世界是三维的. Polycarp突然对四维空间产生了兴趣,他想对四维空间进行一些研究.但是在此之前,他必须先对三维世界了解透彻. 于是Polycar ...

  2. c++ 超长整数加法 高精度加法

    c++ 超长整数加法 高精度加法 实现思路 不能直接使用加法,因为int和long long都已超出最大数据表示范围 数据读入采用string类型,读入后将数据的每一位存储到vector中 vecto ...

  3. 跟着 Guava、Spring 学习如何设计观察者模式

    文章首发在公众号(龙台的技术笔记),之后同步到掘金和个人网站:xiaomage.info 今天讲解一篇行为型设计模式,什么是行为型?行为型主要负责设计 类或对象之间的交互.工作中常用的观察者模式就是一 ...

  4. 论文解读(KP-GNN)《How Powerful are K-hop Message Passing Graph Neural Networks》

    论文信息 论文标题:How Powerful are K-hop Message Passing Graph Neural Networks论文作者:Jiarui Feng, Yixin Chen, ...

  5. 实现领域驱动设计 - 使用ABP框架 - 存储库

    存储库 Repository 是一个类似于集合的接口,领域层和应用程序层使用它来访问数据持久性系统(数据库),以读写业务对象(通常是聚合) 常见的存储库原则是: 在领域层定义一个存储库接口(因为它被用 ...

  6. canvas简易画布

    今天学习了canvas,利用它做了一个简易版的画板,校验自己所学的知识,分享出来以供大家学习指教.先上效果图. 主要是使用了canvas的stroke和clearReact来实现画板的绘画和橡皮擦功能 ...

  7. 从0到1搭建一款页面自适应组件(Vue.js)

    组件将根据屏幕比例及当前浏览器窗口大小,自动进行缩放处理. 建议在组件内使用百分比搭配flex进行布局,以便于在不同的分辨率下得到较为一致的展示效果.使用前请注意将body的margin设为0,否则会 ...

  8. Freeswitch使用originate转dialplan

    概述 Freeswitch是一款非常好用的开源VOIP软交换平台. 最近在对fs做一些功能测试,测试的过程中产生的一个需求,如何从fs发起呼叫并把后续的呼叫流程转到某一个dialplan上,这样在测试 ...

  9. Vue2自定义插件的写法-Vue.use()

    最近在用vue2完善一个项目,顺便温习下vue2的基础知识点! 有些知识点恰好没用到时间一长就会淡忘,这样对自己是一种损失. 定义一个对象 对象里可以有任何内容 但install的函数是必不可少的,因 ...

  10. 聊聊 RPA 方向的规划:简单有价值的事情长期坚持做

    「简单有价值的事情长期坚持做」 这是成功最简单,但也最难学的秘诀.不经过训练,人很难意识到时间复利的威力. 仙剑奇侠传的「十里坡剑神」和金庸群侠传的「十级野球拳」,就是简单的事情持之以恒反复做,最后就 ...