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的更多相关文章

  1. Atcoder Grand Contest 024 E - Sequence Growing Hard(dp+思维)

    题目传送门 典型的 Atcoder 风格的计数 dp. 题目可以转化为每次在序列中插入一个 \([1,k]\) 的数,共操作 \(n\) 次,满足后一个序列的字典序严格大于前一个序列,问有多少种操作序 ...

  2. [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. ...

  3. AtCoder Grand Contest 012

    AtCoder Grand Contest 012 A - AtCoder Group Contest 翻译 有\(3n\)个人,每一个人有一个强大值(看我的假翻译),每三个人可以分成一组,一组的强大 ...

  4. AtCoder Grand Contest 011

    AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\( ...

  5. AtCoder Grand Contest 031 简要题解

    AtCoder Grand Contest 031 Atcoder A - Colorful Subsequence description 求\(s\)中本质不同子序列的个数模\(10^9+7\). ...

  6. AtCoder Grand Contest 010

    AtCoder Grand Contest 010 A - Addition 翻译 黑板上写了\(n\)个正整数,每次会擦去两个奇偶性相同的数,然后把他们的和写会到黑板上,问最终能否只剩下一个数. 题 ...

  7. AtCoder Grand Contest 009

    AtCoder Grand Contest 009 A - Multiple Array 翻译 见洛谷 题解 从后往前考虑. #include<iostream> #include< ...

  8. AtCoder Grand Contest 008

    AtCoder Grand Contest 008 A - Simple Calculator 翻译 有一个计算器,上面有一个显示按钮和两个其他的按钮.初始时,计算器上显示的数字是\(x\),现在想把 ...

  9. AtCoder Grand Contest 007

    AtCoder Grand Contest 007 A - Shik and Stone 翻译 见洛谷 题解 傻逼玩意 #include<cstdio> int n,m,tot;char ...

随机推荐

  1. GoF23种设计模式之结构型模式之外观模式

    一.概述         为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 二.适用性 1.当你要为一个复杂子系统提供一个简单接口的时候.子系统 ...

  2. 我的Python分析成长之路7

    类 一.编程范式: 1.函数式编程   def 2.面向过程编程   (Procedural Programming) 基本设计思路就是程序一开始是要着手解决一个大的问题,然后把一个大问题分解成很多个 ...

  3. 使用nohup+& 踩到的坑

    首先分清楚nohup与&: &是指在后台运行一般在执行命令后,都会显式的在前台执行,当Ctrl+C后进程回宕掉,但是 在命令后加&,即使Ctrl+C,程序还在进行,但是,当关闭 ...

  4. LeetCode(203) Remove LinkedList Elements

    题目 Remove all elements from a linked list of integers that have value val. Example Given: 1 –> 2 ...

  5. 二叉排序树:HUD3999-The order of a Tree(二叉排序树字典序输出)

    The order of a Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

  6. 微信小程序开发 -- 手机振动

    wx.vibrateLong(OBJECT) wx.vibrateLong(OBJECT) 方法使手机发生较长时间的振动(400ms) OBJECT参数说明: 参数名 类型 必填 说明 success ...

  7. 股票交易(DP+单调队列优化)

    题目描述 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi, ...

  8. NuGet安装本地包命令行

    尝试安装本地的NuGet包. 键入 "get-help NuGet" 可查看所有可用的 NuGet 命令. install-package Polly.Net40Async-Sig ...

  9. DS博客作业06—图

    1.本周学习总结 1.1思维导图 1.2学习体会 2.PTA实验作业 2.1 图着色问题 图着色问题是一个著名的NP完全问题.给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色, ...

  10. 九度oj 题目1458:汉诺塔III

    题目描述: 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下.由小到大顺序串着由64个圆盘构成的塔.目的是将最左边杆上的盘全部移到右边的杆上,条件是一次只能移动 ...