[2021.4.9多校省选模拟35]隐形斗篷 (prufer序列,背包DP)
题面
我编不下去了!
给出
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∑ap1i2=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∑ap1i2=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)的更多相关文章
- codehunter 「Adera 6」杯省选模拟赛 网络升级 【树形dp】
直接抄ppt好了--来自lyd 注意只用对根判断是否哟留下儿子 #include<iostream> #include<cstdio> using namespace std; ...
- 6.29 省选模拟赛 坏题 AC自动机 dp 图论
考场上随手构造了一组数据把自己卡掉了 然后一直都是掉线状态了. 最后发现这个东西不是subtask -1的情况不多 所以就没管无解直接莽 写题有点晚 故没调出来.. 考虑怎么做 容易想到建立AC自动机 ...
- 5.13 省选模拟赛 优雅的绽放吧,墨染樱花 多项式 prufer序列 计数 dp
LINK:优雅的绽放吧,墨染樱花 当时考完只会50分的做法 最近做了某道题受到启发 故会做这道题目了.(末尾附30分 50分 100分code 看到度数容易想到prufer序列 考虑dp统计方案数. ...
- 5.4 省选模拟赛 修改 线段树优化dp 线段树上二分
LINK:修改 题面就不放了 大致说一下做法.不愧是dls出的题 以前没见过这种类型的 不过还是自己dp的时候写丑了. 从这道题中得到一个结论 dp方程要写的优美一点 不过写的过丑 优化都优化不了. ...
- 3.29省选模拟赛 除法与取模 dp+组合计数
LINK:除法与取模 鬼题.不过50分很好写.考虑不带除法的时候 其实是一个dp的组合计数. 考虑带除法的时候需要状压一下除法操作. 因为除法操作是不受x的大小影响的 所以要状压这个除法操作. 直接采 ...
- [CSP-S模拟测试]:简单的序列(DP)
题目描述 从前有个括号序列$s$,满足$|s|=m$.你需要统计括号序列对$(p,q)$的数量. 其中$(p,q)$满足$|p|+|s|+|q|=n$,且$p+s+q$是一个合法的括号序列. 输入格式 ...
- 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解
今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...
- 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)
一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...
- 6.28 NOI模拟赛 好题 状压dp 随机化
算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...
随机推荐
- 使用C++的ORM框架QxORM
QxORM中,我们用的最多的无非是这两点 官方表述是这样的: 持久性: 支持最常见的数据库,如 SQLite.MySQL.PostgreSQL.Oracle.MS SQL Server.MongoDB ...
- 不花钱~Python制作视频解析免费追剧神器
同学们在闲暇之余是否喜欢看电影或者电视剧呢? 今天带领大家使用python制作能免费追剧的桌面软件.还在等什么?发车了! 效果我就不再这里演示了https://jq.qq.com/?_wv=1027& ...
- 数组基础篇(对应C++ Primer plus 4.10)
概要:数组是由一组同类型的元素组成的集合,在内存上是一片连续的存储空间.C++提供了三种数组的表示方法:普通数组,模板类vector(C++98 新增的标准模板库STL提供该模板类)和模板类array ...
- PostgreSQL 9.1 飞升之路
PostgreSQL upgrade 以升级 PostgreSQL 9.1 至 PostgreSQL 11 (跨越 9.2.9.3.9.4.9.5.9.6.10 六个大版本) 为例,本文将分享一下过去 ...
- Codeforces Round #779 (Div. 2)
A 题目连接 题目大意 给一个01串,其中每一个长度大于等于2的子区间中0的数量不大于1的数量,最少插入多少1 思路 寻找 00 和 010 00 -->0110 加2 010 --&g ...
- 霍普菲尔得神经网络(Hopfield Neural Network)
设计一个反馈网络存储下列目标平衡点: T = [ 1 -1; -1 1 ]; 并用6组任意随机初始列矢量,包括一组在目标平衡点连线的垂直平分线上的一点作为输入矢量对所设计的网络的平衡点进行测试,观 ...
- labview从入门到出家7(进阶篇)--队列的使用
本节简单讲解队列在Labview中的使用,队列你可以认为就是一组先进先出的数据列表,在Labview中常用来缓存和传递数据.用了这么久的队列,个人认为有个方便的地方在于数据传递的把控,不管是局部变量还 ...
- 攻防世界MISC—进阶区21-30
21.easycap 得到一个pcap文件,协议分级统计,发现都是TCP协议 直接追踪tcp流,得到FLAG 22.reverseMe 得到一张镜面翻转的flag,放入PS中,图像-图像旋转-水平翻转 ...
- 攻防世界MISC—进阶区1-10
1.something_in_image zip中的文件用010 Editor打开后直接搜索flag,即可找到flag 2.wireshark-1 zip内是pcap文件,打开后根据题目知道要寻找登录 ...
- 05 MySQL_主键约束
主键约束 主键: 用于表示数据唯一性的字段称为主键: 约束:就是对表字段添加限制条件 主键约束:保证主键字段的值唯一且非空: - 格式 : create table t1(id int primary ...