Atcoder Grand Contest 024
A
略
B
略
C
略
D(构造分形)
题意:
给出一个由n个点的组成的树,你可以加一些点形成一个更大的树。对于新树中的两个点i和j,如果以i为根的树与以j为根的树是同构的那么i和j颜色可以相同。问最少需要多少颜色,在颜色最少的情况下,最少需要多少叶子节点。
n<=100
分析:
根据给的样例画一画,就明白是需要把树补成一个“分形”的结构,那么离分形中心距离一样的点就是同颜色的,于是我们希望最小化离中心最大的点的距离
也就是说最少颜色一定是树的直径的一半,于是我们自然想到把直径拉出来,取中间的那个点为分形中心
但良心的样例告诉我们,这样取不一定会让叶子节点的个数最少,你可以把一条边作为分形中心,分成左右两个分形,而且这个边可能也不在直径上
考虑到n<=100,我们不妨枚举哪个点作为中心,枚举哪个边作为中心,去取一个最小值即可
时间复杂度O(n^2)
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
vector<int> g[maxn+];
int n,s,t;
int fa[maxn+],dep[maxn+],a[maxn+];
long long ans;
void dfs(int k,int last)
{
dep[k]=dep[last]+;
fa[k]=last;
int d=;
for(auto u:g[k])
{
if(u==last) continue;
dfs(u,k);
++d;
}
a[dep[k]]=max(a[dep[k]],d);
}
int main()
{
scanf("%d",&n);
for(int i=;i<n;++i)
{
int u,v;
scanf("%d%d",&u,&v);
g[u].push_back(v),g[v].push_back(u);
}
dfs(,);
for(int i=;i<=n;++i)
if(dep[i]>dep[s]) s=i;
dfs(s,);
for(int i=;i<=n;++i)
if(dep[i]>dep[t]) t=i;
//printf("%d %d\n",s,t);
int ans1=(dep[t]+)/;
printf("%d ",ans1);
for(int i=;i<=n;++i)
{
memset(a,,sizeof(a));
a[]=;
dfs(i,);
long long res=;
for(int j=;j<=n;++j)
if(a[j]==) break;else res=res*a[j];
if(a[ans1]!=) continue;
if(ans==||res<ans) ans=res;
}
for(int u=;u<=n;++u)
for(auto v:g[u])
{
memset(a,,sizeof(a));
a[]=;
dep[u]=;
dfs(v,u);
dep[v]=;
dfs(u,v);
long long res=;
for(int j=;j<=n;++j)
if(a[j]==) break;else res=res*a[j];
if(a[ans1]!=) continue;
if(ans==||res<ans) ans=res;
}
printf("%lld\n",ans);
return ;
}
E(计数)
题意:
给定一个n和k,我们构造一组A0,A1,...,An
其中Ai是一个有i个元素的数列,每个数的范围是1~k
若Ai-1是Ai的子序列且字典序满足Ai>Ai-1,则我们称这一组A是合法的,问一共有多少种合法的A,答案对M取模。
n,k<=300,m<=1e9
分析:
我们考虑第i次操作,加入一个编号为i的点,这个点的权值就是Ai中多加的数字x,把其放到Ai-1中哪个位置的前面,就把这个点的父亲连到那个点
然后我们考虑字典序限制,x必须放到一个比x小的数字前面(如果放到相同的前面,实际上等价于放在连续段的最后一个)
于是就变成了一个有n+1个节点的树,然后每个点的权值都比孩子的权值大,每个点的编号都比孩子的编号小,一个树和一个A是一一对应的,于是我们对这个树计数就行了
dp[i][j]表示有i个点的树,root的权值是j情况下的方案数,那怎么转移呢?
我们去枚举1号点所在的子树的节点个数和1号点的权值去转移
这样是四次方的,但写出式子发现可以前缀和优化,于是就是O(n^3)
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
typedef long long ll;
int n,m,mod;
ll dp[maxn+][maxn+],sum[maxn+][maxn+],c[maxn+][maxn+];
void work(ll &a,ll b)
{
a=(a+b)%mod;
if(a<) a+=mod;
}
int main()
{
scanf("%d%d%d",&n,&m,&mod);
c[][]=;
for(int i=;i<=n+;++i)
{
c[i][]=;
for(int j=;j<=i;++j) c[i][j]=(c[i-][j]+c[i-][j-])%mod;
}
for(int i=;i<=m;++i) dp[][i]=;
sum[][]=;
for(int i=;i<=m;++i) sum[][i]=(sum[][i-]+dp[][i])%mod;
for(int i=;i<=n+;++i)
{
for(int j=;j<=m;++j)
for(int k=;k<i;++k)
work(dp[i][j],dp[i-k][j]*c[i-][k-]%mod*(sum[k][m]-sum[k][j])%mod);
sum[i][]=dp[i][];
for(int j=;j<=m;++j) sum[i][j]=(sum[i][j-]+dp[i][j])%mod;
}
printf("%lld\n",dp[n+][]);
return ;
}
F(DAG图dp)
题意:
给定一些01字符串 ,现在你找一个01字符串s,如果给定的这些01字符串里至少有m个字符串包含s作为子序列,那么s就是合法的。对于所有合法的s,找到长度最长的(在这基础上找字典序最小的)
01字符串的给定方式见题面
分析:
如果我们可以求出长度<=n的所有字符串被多少个给定字符串包含作为子序列,那么这个问题就能轻松解决了
我们如何描述一个字符串的所有子序列呢?
我们用s[t]表示已经固定了s,然后取t中的子序列
那么s[t]可以转移到s0[t'] s1[t']
并且这个dag有一个性质,就是任意两个点的路径个数<=1
所以就可以在这个dag图上进行dp
时间复杂度O(2^n*n^2)
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
int dp[][+][<<maxn],nx[+][<<maxn][];
char s[<<maxn];
int n,m,ans,len;
int main()
{
scanf("%d%d",&n,&m);
int now=;
for(int i=;i<=n;++i)
{
scanf("%s",s);
for(int j=;j<(<<i);++j)
if(s[j]=='') dp[now][i][j]=;
}
for(int i=;i<=n;++i)
for(int j=;j<(<<i);++j)
{
nx[i][j][]=nx[i][j][]=-;
for(int k=i-;k>=;--k)
if((j>>k)&)
{
nx[i][j][]=k;
break;
}
for(int k=i-;k>=;--k)
if(((j>>k)&)==)
{
nx[i][j][]=k;
break;
}
}
for(int i=;i<n;++i)
{
for(int j=n-i;j>=;--j)
for(int s=(<<(i+j))-;s>=;--s)
{
if(!dp[now][i+j][s]) continue;
int t=nx[j][s&((<<j)-)][];
if(t!=-)
dp[now^][i+t+][(s>>j<<t+)|(s&(<<(t+))-)]+=dp[now][i+j][s];
t=nx[j][s&((<<j)-)][];
if(t!=-)
dp[now^][i+t+][(s>>j<<t+)|(s&(<<(t+))-)]+=dp[now][i+j][s];
}
memset(dp[now],,sizeof(dp[now]));
now^=;
for(int j=;i++j<=n;++j)
for(int s=;s<<<(i++j);++s)
dp[now][i+][s>>j]+=dp[now][i++j][s];
for(int s=(<<(i+))-;s>=;--s)
{
if(dp[now][i+][s]>=m) len=i+,ans=s;
}
}
for(int i=len-;i>=;--i)
if(ans&(<<i)) printf("");else printf("");
return ;
}
Atcoder Grand Contest 024的更多相关文章
- Atcoder Grand Contest 024 E - Sequence Growing Hard(dp+思维)
题目传送门 典型的 Atcoder 风格的计数 dp. 题目可以转化为每次在序列中插入一个 \([1,k]\) 的数,共操作 \(n\) 次,满足后一个序列的字典序严格大于前一个序列,问有多少种操作序 ...
- [AtCoder Grand Contest 024 Problem E]Sequence Growing Hard
题目大意:考虑 N +1 个数组 {A0,A1,…,AN}.其中 Ai 的长度是 i,Ai 内的所有数字都在 1 到 K 之间. Ai−1 是 Ai 的子序列,即 Ai 删一个数字可以得到 Ai−1. ...
- AtCoder Grand Contest 012
AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...
- AtCoder Grand Contest 011
AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...
- AtCoder Grand Contest 031 简要题解
AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...
- AtCoder Grand Contest 010
AtCoder Grand Contest 010 A - Addition 翻译 黑板上写了\(n\)个正整数,每次会擦去两个奇偶性相同的数,然后把他们的和写会到黑板上,问最终能否只剩下一个数. 题 ...
- AtCoder Grand Contest 009
AtCoder Grand Contest 009 A - Multiple Array 翻译 见洛谷 题解 从后往前考虑. #include<iostream> #include< ...
- AtCoder Grand Contest 008
AtCoder Grand Contest 008 A - Simple Calculator 翻译 有一个计算器,上面有一个显示按钮和两个其他的按钮.初始时,计算器上显示的数字是\(x\),现在想把 ...
- AtCoder Grand Contest 007
AtCoder Grand Contest 007 A - Shik and Stone 翻译 见洛谷 题解 傻逼玩意 #include<cstdio> int n,m,tot;char ...
随机推荐
- ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph(有源上下界最大流 模板)
关于有源上下界最大流: https://blog.csdn.net/regina8023/article/details/45815023 #include<cstdio> #includ ...
- poj 3176 三角数和最大问题 dp算法
题意:给一个三角形形状的数字,从上到下,要求数字和最大 思路 :dp dp[i+1][j]=max(dp[i+1][j],dp[i][j]+score[i+1][j]) dp[i+1][j+1]=ma ...
- css 透明度使用
设置元素整体透明度: div{ opacity: 0.5; } 设置背景色透明度 div{ background: rgba(0,0,0,0.5); }
- Ubuntu关机与重启的相关指令
将数据同步写入到磁盘中的指令:sync 惯用的关机指令:shutdown 重新启动,关机:reboot,halt,poweroff shutdown可完成如下工作: 1.可以自由选择关机模式:是要关机 ...
- Selenium WebDriver-网页的前进、后退、刷新、最大化、获取窗口位置、设置窗口大小、获取页面title、获取网页源码、获取Url等基本操作
通过selenium webdriver操作网页前进.后退.刷新.最大化.获取窗口位置.设置窗口大小.获取页面title.获取网页源码.获取Url等基本操作 from selenium import ...
- Leetcode207--->课程表(逆拓扑排序)
题目: 课程表,有n个课程,[0, n-1]:在修一个课程前,有可能要修前导课程: 举例: 2, [[1,0]] 修课程1前需要先修课程0 There are a total of 2 courses ...
- loadrunner参数化数据分配方法
数据分配方法: 在“Select next row“列表中选择一个数据分配方法,以指示在Vuser脚本执行期间如何从参数文件中取得数据.选项包括”Sequential“.“Random”.“Uniqu ...
- 04-python进阶-map&reduce
Map --映射 Reduce -- 归纳 将大数据标准化的处理 Map 拆封任务,Reduce将结果合并 这样是不是能够将很多计算机组成一台超级计算机呢? 一些问题:如果任务本身就很复杂,那么拆解任 ...
- python递归深度报错--RuntimeError: maximum recursion depth exceeded
当你的程序递归的次数超过999次的时候,就会引发RuntimeError: maximum recursion depth exceeded. 解决方法两个: 1.增加系统的递归调用的次数: impo ...
- spl_autoload_register和__autoload
1.实例化一个未定义的类时会触发 2.类存在继承关系时,被继承的类没有引入的情况下,会触发 (继承关系的两个类必须在同一个目录下) __autoload 实例化PRINTIT类,'PRINTIT'作 ...