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 ...
随机推荐
- python-numpy-pandas
目录 numpy 模块 创建矩阵方法: 获取矩阵的行列数 切割矩阵 矩阵元素替换 矩阵的合并 通过函数创建矩阵 矩阵的运算 pandas模块 series (一维列表) DataFrame DataF ...
- Python使用ORM控制MongoDB(MongoEngine)
简介: MongoEngine是一个对象文档映射器(ODM),相当于一个基于SQL的对象关系映射器(ORM) pymongo来操作MongoDB数据库,但是直接把对于数据库的操作代码都写在脚本中,这会 ...
- stm32之PWM学习
下图是一个STM32普通PWM形成的图形原理说明 自动重装载寄存器(ARR)用于确定波形的频率(即周期).捕获比较寄存器(CCRx)(用于确定占空比的) PWM的工作过程如下:首先ARR寄存器里面的值 ...
- micrium ucprobe使用笔记
前段时间在学习ucos-iii的时候,用到了micrium ucprobe,发现在调试的时候,很方便,可以直观的看到任务的运行使用情况,全局变量的值变化等,当然详细的可以参考官方文档,也可以参考网上的 ...
- Persona5
65536K Persona5 is a famous video game. In the game, you are going to build relationship with your ...
- 使用sprunge粘贴文字
在irc里面请教的时候,需要输出很多文本,irc禁止输入多行文字. 使用sprunge可以返回一个网址,省去复制粘贴的麻烦. 1> 简单使用: command | curl -F "s ...
- Android之高效率截图
本文来自网易云社区 作者:孙圣翔 在一张Android手机上截图有好多办法,为了能够高效率的截图,我几乎把所有的方法都尝试了一般.走了好多路,也遇到了好多的问题. 只是想记录下这其中的不容易. 下面所 ...
- Selenium WebDriver- 使用Frame中的HTML源码内容操作Frame
#encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webdriver i ...
- python - unittest - testsuite and runner
前置条件: 测试用例部分或全部编写完成 一. 生成测试集 1. 方法1 - 通过加载函数来加载测试用例 import unittest from TestCase.test_login import ...
- P2258 子矩阵 (搜索,动态规划)
题目链接 Solution 搜索+DP. 刚好把搜索卡死的数据范围... 然后应该可以很容易想到枚举行的情况,然后分列去DP. 行的情况直接全排列即可,复杂度最高 \(O(C_{16}^{8})\). ...