DAY4共2题:

  • 树(组合数学)

  • 子序列(dp,数学)

作者:Eriktse

简介:19岁,211计算机在读,现役ACM银牌选手力争以通俗易懂的方式讲解算法!️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)

原文链接(阅读原文获得更好阅读体验):https://www.eriktse.com/algorithm/1095.html

题目传送门:https://ac.nowcoder.com/acm/problem/13611

通过观察条件“一个染色方案是合法的,当且仅当对于所有相同颜色的点对(x,y),x到y的路径上的所有点的颜色都要与x和y相同。”我们可以发现,当且仅当染色的点可以全部连通时可以满足条件。

所以现在问题是如何将n个点划分为k块。

我们可以发现在树上,任意删除一条边都会使得联通块个数 + 1

其实块数只要<= k即可,因为我们可以有一些颜色不使用。所以要划分为i块,只需要从n - 1条边中任选i - 1条进行删除即可,方案数是C(n - 1, i - 1)

假设现在我们得到了i (i <= k)个联通块,需要将i种颜色染上去,首先需要C(k, i)种方法取出颜色,然后A(i, i)一个全排列将颜色染上去。

所以答案公式如下:

$$ans=\sum_{i=1}^{k}C(n - 1, i - 1)C(k, i)i!$$

可能涉及一些快速幂乘法逆元的知识,需要自行学习。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 350, p = 1e9 + 7; int fac[maxn]; int qmi(int a, int b)
{
int res = 1;
while(b)
{
if(b & 1)res = res * a % p;
a = a * a % p, b >>= 1;
}
return res;
} int inv(int x){return qmi(x, p - 2);} int C(int n, int m)
{
if(n < m || n < 0 || m < 0)return 0;
return fac[n] * inv(fac[n - m] * fac[m] % p) % p;
} signed main()
{
int n, k;scanf("%lld %lld", &n, &k);
fac[0] = 1;
for(int i = 1;i <= n; ++ i)fac[i] = fac[i - 1] * i % p; int ans = 0;
for(int i = 1;i <= n; ++ i)//分为i块
{
int tmp = C(n - 1, i - 1) * C(k, i) % p * fac[i] % p;
ans = (ans + tmp) % p;
}
printf("%lld\n", ans);
return 0;
}

子序列

题目传送门:https://ac.nowcoder.com/acm/problem/17065

小技巧:观察数据范围,比较小,应该可以容纳O(n^3)的复杂度,所以可以大胆考虑dp。

首先定义状态dp[i][j]表示以第i个元素结尾,且长度为j的序列的个数

再考虑一下转移,题目中的条件可以进行一些转换:

$${a_{p_i}}^{p_j} < {a_{p_j}}^{p_i}$$

等价于:

$$ \frac{log(a_{p_i})}{p_i} < \frac{log(a_{p_j})}{p_j} $$

我们可以记:

$$ b_i = \frac{log(a_{p_i})}{p_i} $$

也就是说对于选出的子序列中的每一个元素,他们满足一个偏序关系,只要我的b[j] > b[i],那么b[j]将会大于所有的b[k] (k < i)

所以我们可以考虑以下的转移:

$$dp_{i, j} = \sum_{k=1}^{i - 1}[b_i > b_k] \times dp_{k, j - 1}$$

考虑初始化,当最后一个元素确定,序列长度为1(j = 1)时,方案仅有1种。

最后的答案是将所有情况加起来(注意取模,不过这道题数据较弱,不取模也可以过)。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 109, p = 1e9 + 7; //dp[i][j]表示以第i个元素结尾,长度为j的方案数
int a[maxn], dp[maxn][maxn]; signed main()
{
int n;scanf("%lld", &n);
for(int i = 1;i <= n; ++ i)scanf("%lld", a + i); for(int i = 1;i <= n; ++ i)
{
dp[i][1] = 1;
for(int j = 1;j <= i; ++ j)
{
for(int k = 1; k < i; ++ k)
{
if(log(a[k]) / k < log(a[i]) / i)
{
dp[i][j] += dp[k][j - 1];
dp[i][j] %= p;
}
}
}
} int ans = 0;
for(int i = 1;i <= n; ++ i)
for(int j = 1;j <= i; ++ j)
{
ans = (ans + dp[i][j]) % p;
}
printf("%lld\n", ans);
return 0;
}

本文由eriktse原创,创作不易,如果对您有帮助,欢迎小伙伴们点赞、收藏、留言

【ACM算法竞赛日常训练】DAY4题解与分析【树】【子序列】| 组合数学 | 动态规划的更多相关文章

  1. 【经验总结】Java在ACM算法竞赛编程中易错点

    一.Java之ACM易错点 1. 类名称必须采用public class Main方式命名 2. 在有些OJ系统上,即便是输出的末尾多了一个“ ”,程序可能会输出错误,所以在我看来好多OJ系统做的是非 ...

  2. ACM算法竞赛:抄课文

    题目如下: 比如现在要写一句话 Hello world 输入: n (n > 0) 比如输入的n为10,就将Hello world打印十 #include <stdio.h> #in ...

  3. 华南师大 2017 年 ACM 程序设计竞赛新生初赛题解

    题解 被你们虐了千百遍的题目和 OJ 也很累的,也想要休息,所以你们别想了,行行好放过它们,我们来看题解吧... A. 诡异的计数法 Description cgy 太喜欢质数了以至于他计数也需要用质 ...

  4. 算法竞赛入门经典训练指南——UVA 11300 preading the Wealth

    A Communist regime is trying to redistribute wealth in a village. They have have decided to sit ever ...

  5. (Step1-500题)UVaOJ+算法竞赛入门经典+挑战编程+USACO

    http://www.cnblogs.com/sxiszero/p/3618737.html 下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年 ...

  6. 算法竞赛入门经典+挑战编程+USACO

    下面给出的题目共计560道,去掉重复的也有近500题,作为ACMer Training Step1,用1年到1年半年时间完成.打牢基础,厚积薄发. 一.UVaOJ http://uva.onlinej ...

  7. ACM算法锦集

    一:知识点 数据结构: 1,单,双链表及循环链表 2,树的表示与存储,二叉树(概念,遍历)二叉树的 应用(二叉排序树,判定树,博弈树,解答树等) 3,文件操作(从文本文件中读入数据并输出到文本文 件中 ...

  8. 2015浙江财经大学ACM有奖周赛(一) 题解报告

    2015浙江财经大学ACM有奖周赛(一) 题解报告 命题:丽丽&&黑鸡 这是命题者原话. 题目涉及的知识面比较广泛,有深度优先搜索.广度优先搜索.数学题.几何题.贪心算法.枚举.二进制 ...

  9. Aho-Corasick automaton(AC自动机)解析及其在算法竞赛中的典型应用举例

    摘要: 本文主要讲述了AC自动机的基本思想和实现原理,如何构造AC自动机,着重讲解AC自动机在算法竞赛中的一些典型应用. 什么是AC自动机? 如何构造一个AC自动机? AC自动机在算法竞赛中的典型应用 ...

  10. 算法竞赛入门经典 LA 4329(树状数组)

    题意: 一排有着不同能力值的人比赛,规定裁判的序号只能在两人之间,而且技能值也只能在两人之间 问题: <算法竞赛入门经典-训练指南>的分析: 上代码: #include<iostre ...

随机推荐

  1. Java输入输出格式

    一.输入字符串 Scanner in=new Scanner(System.in); String str1=in.next(); //输入一个字符串,以空格或回车结束 String str2=in. ...

  2. 微信浏览器h5页面开发遇到问题

    1.ios不支持window.open(),要创建a链接 let elink = document.createElement('a'); elink.href = baseURL+'/onlineC ...

  3. Flink状态后端的对比及机制

    1. Flink状态后端的类型: MemoryStateBackend FsStateBackend RocksDBStateBackend 2. 各状态后端对比: 2.1 MemoryStateBa ...

  4. EBI数据库下载数据

    EBI网址链接: https://www.ebi.ac.uk 方法:直接从ncbi上面找到想要下载数据的SRR号然后去EBI里面直接搜索即可得到. 底部就是想要下载的fastq文件了: 然后右键复制链 ...

  5. python3GUI--用Tk开发一款恶搞蓝屏软件(附源码)

    目录 一.准备工作 1.Tkinter 2.科普-电脑蓝屏 二.预览 1.蓝屏-win10.win11(中文版) 2.蓝屏-win10.win11(英文版) 3.Windows其他版本(XP.Win7 ...

  6. CSS 选择器-认识并应用选择器

    在内嵌式和外部css中,要想将CSS样式应用于特定的HTML元素,首先需要找到该目标元素,这时需要用到CSS中的选择器. 选择器:选择要添加样式的 HTML 标签的一种方法.模式. 首先学习 css2 ...

  7. mysql_记录操作

    在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括 使用INSERT实现数据的插入 UPDATE实现数据的更新 使用DELETE实现数据的删除 使用SELECT查询数据以及 ...

  8. P2212 Watering the Fields S

    题目描述 给定n个点,第i个点的坐标为(xi,yi)(xi​,yi​),如果想连通第i个点与第j个点,需要耗费的代价为两点的距离.第i个点与第j个点之间的距离使用欧几里得距离进行计算,即:(xi-xj ...

  9. 3vue

    阻止冒泡 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  10. JS样式获取的封装方法

    样式获取 style属性 只能获取标签内容style属性里面存在的一些样式 如果你需要获取对应的全局所有地方设置样式 我们就需要采用一些方法 getComputedStyle 方法属于window的方 ...