codeforces814E
https://lunch.blog.luogu.org/cf814e-an-unavoidable-detour-for-homedp-ji-shuo-post
https://blog.csdn.net/qq_31759205/article/details/77715991
An unavoidable detour for home
CodeForces - 814E
Those unwilling to return home from a long journey, will be affected by the oddity of the snail and lose their way. Mayoi, the oddity's carrier, wouldn't like this to happen, but there's nothing to do with this before a cure is figured out. For now, she would only like to know the enormous number of possibilities to be faced with if someone gets lost.
There are n towns in the region, numbered from 1 to n. The town numbered 1 is called the capital. The traffic network is formed by bidirectional roads connecting pairs of towns. No two roads connect the same pair of towns, and no road connects a town with itself. The time needed to travel through each of the roads is the same. Lost travelers will not be able to find out how the towns are connected, but the residents can help them by providing the following facts:
- Starting from each town other than the capital, the shortest path (i.e. the path passing through the minimum number of roads) to the capital exists, and is unique;
- Let li be the number of roads on the shortest path from town i to the capital, then li ≥ li - 1 holds for all 2 ≤ i ≤ n;
- For town i, the number of roads connected to it is denoted by di, which equals either 2 or 3.
You are to count the number of different ways in which the towns are connected, and give the answer modulo 109 + 7. Two ways of connecting towns are considered different if a pair (u, v) (1 ≤ u, v ≤ n) exists such there is a road between towns u and v in one of them but not in the other.
Input
The first line of input contains a positive integer n (3 ≤ n ≤ 50) — the number of towns.
The second line contains n space-separated integers d1, d2, ..., dn (2 ≤ di ≤ 3) — the number of roads connected to towns 1, 2, ..., n, respectively. It is guaranteed that the sum of di over all i is even.
Output
Output one integer — the total number of different possible ways in which the towns are connected, modulo 109 + 7.
Examples
4
3 2 3 2
1
5
2 3 3 2 2
2
5
2 2 2 2 2
2
20
2 2 2 2 3 2 3 2 2 2 2 2 2 2 2 2 2 3 3 2
82944
Note
In the first example, the following structure is the only one to satisfy the constraints, the distances from towns 2, 3, 4 to the capital are all 1.
In the second example, the following two structures satisfy the constraints.
/*
g的状态转移:
①当i=j=k=0时,g[i][j][k]=1
②当 j=0,k>0时,g[i][j][k]=∑g[i][j][k-1-l]*c[k-1][l]*(l!)/2 l∈[2,k-1]
表示从前k-1个度数能变成3的点中选l个点出来与最后一个点构成环,这l+1度数都变成3
③当i=0,j>0或k>0时,g[i][j][k]=g[i][j-2][k]*(j-1)+g[i][j][k-1]*k
前一部分:表示从j-1个度数能变成2的点中选一个出来与最后一个点相连,这2个点的度数都变成2
后一部分:表示从k个度数能变成2的点中选一个出来与最后一个点相连,这个点变成度数3,最后一个点变成度数2
④当i>0时,g[i][j][k]=g[i-1][j-1][k]*j+g[i-1][j+1][k-1]*k
前一部分:表示从j个度数能变成2的点中选一个出来与最后一个点相连,这个点变成度数2
后一部分:表示从k个度数能变成3的点钟选一个出来与最后一个点相连,这个点变成度数3
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
ll s=; bool f=; char ch=' ';
while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
while(isdigit(ch)) {s=(s<<)+(s<<)+(ch^); ch=getchar();}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<) {putchar('-'); x=-x;}
if(x<) {putchar(x+''); return;}
write(x/); putchar((x%)+'');
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=;
const ll Mod=;
int n,deg[N];
ll fac[N],C[N][N];
ll ans=,dp[N][N],g[N][N][N];
/*
dp[i][j]表示前i个节点分为若干层,最后一层有j个节点的方案数
g[i][j][k]表示当前这层有i个节点,上一层有j个度数为2,k个度数为3的
*/
inline void Ad(ll &x,ll y)
{
x+=y; x-=(x>=Mod)?Mod:;
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("my.out","w",stdout);
int i,j,k,l,c2,c3;
R(n);
for(i=;i<=n;i++) R(deg[i]);
fac[]=fac[]=; fac[]=; for(i=;i<=n;i++) fac[i]=fac[i-]*i%Mod; //fac[i]=(i!)/2;
C[][]=;
for(i=;i<=n;i++)
{
C[i][]=; for(j=;j<=n;j++) C[i][j]=(C[i-][j-]+C[i-][j])%Mod;
}
g[][][]=;//i=0就是最下面的时候,要把最后一层连好的方案数
for(j=;j<=n;j++) for(k=;k<=n-j;k++)
{
if(j==&&k>)
{
for(l=;l<=k-;l++) Ad(g[][j][k],g[][j][k-l-]*C[k-][l]%Mod*fac[l]%Mod);//新加的点凑个环
}
else
{
if(j>=) Ad(g[][j][k],g[][j-][k]*(j-)%Mod);//度数为2的必须成对加
if(k>=) Ad(g[][j][k],g[][j][k-]*k%Mod);
}
}
for(i=;i<=n;i++)
{
for(j=;j<=n-i;j++) for(k=;k<=n-i-j;k++)
{
if(j>=) Ad(g[i][j][k],g[i-][j-][k]*j%Mod);
if(k>=) Ad(g[i][j][k],g[i-][j+][k-]*k%Mod);
}
}
// for(i=0;i<=n;i++) for(j=0;j<=n;j++) for(k=0;k<=n;k++)
// {
// cout<<i<<' '<<j<<' '<<k<<' '<<g[i][j][k]<<endl;
// }
dp[deg[]+][deg[]]=;
for(i=deg[]+;i<=n;i++)
{
for(j=;j<=i-deg[]-;j++) //从第三层开始
{
c2=; c3=;
for(k=;k<=i-j;k++)//枚举上一层有k个点
{
if(deg[i-j-k+]==) c2++; else c3++;
Ad(dp[i][j],dp[i-j][k]*g[j][c2][c3]%Mod);
}
}
}
c2=; c3=;
for(i=;i<n;i++)
{
if(deg[n-i+]==) c2++; else c3++;
Ad(ans,dp[n][i]*g[][c2][c3]%Mod);
}
Wl(ans);
return ;
}
codeforces814E的更多相关文章
- Noip前的大抱佛脚----赛前任务
赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...
随机推荐
- java小工具:通过URL连接爬取资源(图片)
java语言编写一个简单爬取网站图片工具,实现简单: 通过 java.net.HttpURLConnection 获取一个URL连接 HttpURLConnection 连接成功返回一个java.io ...
- 【vue】过滤器的使用
一.在methods中使用过滤器------全局定义的过滤器 //main.js中 import Vue from 'vue' Vue.filter('testFilter1',function(va ...
- kong命令(三)route
介绍 route 是一套匹配客户端请求的规则.每个route都会匹配一个service,每个service可定关联多个route. 可以说service:route=1:n.一对多的关系.每个匹配到r ...
- python实现暴力破解
import urllib2 import urllib import cookielib import threading import sys import Queue from HTMLPars ...
- Python练习_集合和深浅拷贝_day7
1. 1.作业 1.把列表中所有姓周的人的信息删掉(升级题:此题有坑, 请慎重): lst = ['周老二', '周星星', '麻花藤', '周扒皮'] 结果: lst = ['麻花藤'] 2.车牌区 ...
- POJ2503(Babelfish)--简单字典树
思路:就是用一个字典树翻译单词的问题,我们用题目中给出的看不懂的那些单词建树,这样到每个单词的叶子结点中存放原来对应的单词就好. 这样查询到某个单词时输出叶子结点存的就行,查不到就"en&q ...
- 六、TreeMap的使用 及其源码解析
TreeMap中的元素默认按照keys的自然排序排列 1. 构造函数TreeMap(): 创建一个空的TreeMap ,keys按照自然排序TreeMap(Comparator comparator) ...
- friend
#include <iostream> using namespace std; //friend 友元,效率的问题 //get 方法和set方法,是标准封装的结果,friend破坏了这种 ...
- TreeMap核心源码实现解析
TreeMap实现了SotredMap接口,它是有序的集合.而且是一个红黑树结构,每个key-value都作为一个红黑树的节点.如果在调用TreeMap的构造函数时没有指定比较器,则根据key执行自然 ...
- 案例:selenium实现登录处理弹窗
func.py https://www.cnblogs.com/andy9468/p/10899508.html main.py中 # 导入webdriver import os import tim ...