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. linux安装等

    软碟通刻入某版本linux 推荐方法 2) 1) U盘启动 修改vmlinuz initrd=initrd.img linux dd quiet 查看U盘盘符 重启修改hd:/dev/sd** qui ...

  2. 独显坏掉,openSUSE启动黑屏卡死

    我的Dell Vostro 1440配置双显卡,独显是 AMD 的.可能是因为散热的问题,独显烧坏了.原先每次启动都有 openSUSE 的圆形启动动画,显卡烧坏后,启动动画变成三个点. 装 Debi ...

  3. CORS预检

    CORS是一种常见的跨域机制,一般由服务端提供一个Access-Control-Allow-Origin头来解决问题,但是这仅对一些"简单请求"有效.那么何谓"简单请求& ...

  4. 循环结构(Java)

    基本介绍 while循环语法 while(布尔表达式){循环内容} 只要布尔表达式为true,循环则会一直循环下去 我们大多数会让循环停止下来,我们需要一个让表达式失效的方式来结束循环 少部分需要循环 ...

  5. 机制设计原理与应用(三)Screening

    目录 3 Screening 3.1 为单个不可分割的项目定价 3.1.1 对\(\theta\)的假设 3.1.2 问题描述 3.1.3 特性 3.2 为无限可分的项目定价 3.2.1 对\(\th ...

  6. django rest 自定义返回数据接口和异常处理

    参考 Django rest framework自定义返回数据格式 一.简介 drf 默认返回的异常格式是这样的 1 { 2 "username": [ 3 "该字段是必 ...

  7. python3GUI--轮播图效果展示By:PyQt5(附源码下载地址)

    @ 目录 一.前言 二.展示 1.酷我音乐 2.QQ飞车 3.虎牙 4.网易云音乐 5.英雄联盟 6.英雄联盟(Pro) 7.腾讯视频 三.源代码 1.demo02GUI.py 2.engine.py ...

  8. percona mongo热备

    https://www.percona.com/doc/percona-server-for-mongodb/LATEST/hot-backup.html#hot-backup Hot Backup ...

  9. SpringMvc配置和原理

    运行原理 DispatcherServlet通过HandlerMapping在MVC的容器中找到处理请求的Controller,将请求提交给Controller,Controller对象调用业务层接口 ...

  10. .net 反射简单介绍

    1.什么是反射 反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类.结构.委托.接口和枚举等)的成员和成员的信息.有了反射,即可对每一个类型了如指掌.另外我还可以直 ...