Problem

CSA-Beta Round#3

题意概要:给定 \(n\) 个数组成的序列,定义一次操作:

  • 在当前序列中选择两个数,将其中较小的数从序列中删除(若两个数相同,则删除在序列中更靠前的)
  • 较大的数为此次操作的花费

进行 \(n-1\) 次操作后只剩一个数,求有多少种不同的执行方案,满足其花费为所有方案中花费最少的

Solution

发现网上没有什么CSA方面的资料?

首先有一个贪心,就是将数字排序离散后压缩一下,若数字 \(i\) 有 \(s_i\) 个,则一定先来 \(s_i-1\) 次花费为零的操作(每次选择两个 \(i\)),剩下的一个 \(i\) 一定是被一个 \(i+1\) 删除

然后考虑用操作的拓扑图来统计……没辙,正解是序列 \(dp\)

先设 \(dp[i]\) 表示 \(i\) 个相同的数字互相消除直至只剩一个数字的方案数,易得 \(dp[n] = \prod_{i=2}^n\frac {i(i-1)}2\)

再考虑设 \(f[i]\) 为前 \(i\) 堆数字已经消成只剩一个的方案数

考虑在处理完前 \(i-1\) 堆的基础上加入第 \(i\) 堆,不妨枚举在第 \(i-1\) 堆的最后一个元素被消除之前有多少个 \(i\) 被消除了,易得:

\[f[i]=\sum_{x=0}^{s_i-1}f[i-1]\cdot dp[s_i](s_i-x)\binom {\sum_{j=1}^{i-1}s_i-1+x}x
\]

一个个解释:

  • \(f[i-1]\):前 \(i-1\) 堆消成一个 \(i-1\) 的方案数
  • \(dp[s_i]\):这 \(s_i\) 个 \(i\) 消成一个的方案数
  • \(s_i-x\):前 \(i-1\) 堆消剩下的那一个 \(i-1\) 需要从剩下的 \(s_i-x\) 个 \(i\) 中挑一个消它
  • \(\binom {\sum_{j=1}^{i-1}s_i-1+x}x\):考虑将这 \(x\) 个提前消的融入前面的消除序列(这里不使用排列是因为这 \(x\) 个 \(i\) 内部之间的前后关系已经在 \(dp[s_i]\) 中考虑过了)

总的来说,就是将 \(s_i\) 分为两段,一份放入前面一起大排队,另一份用来消剩下的那个 \(i-1\)

复杂度 \(O(\sum s_i)=O(n)\)

Code

#include <bits/stdc++.h>
typedef long long ll; inline void read(int&x){
char ch=getchar();x=0;while(!isdigit(ch))ch=getchar();
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
} const int N = 101000, p = 1e9+7;
int a[N], sum[N], f[N], dp[N], n; inline int qpow(int A, int B) {
int res = 1; while(B) {
if(B&1) res = (ll)res * A%p;
A = (ll)A * A%p, B >>= 1;
} return res;
} int fac[N], inv[N];
inline int C(const int nn, const int mm) {return (ll)fac[nn] * inv[mm]%p * inv[nn-mm]%p;} int main() {
read(n);
for(int i=1;i<=n;++i) read(a[i]);
std::sort(a+1,a+n+1); dp[0] = dp[1] = fac[0] = fac[1] = 1;
for(int i=2;i<=n;++i) {
fac[i] = (ll)fac[i-1] * i%p;
dp[i] = ((ll)i * (i-1) >> 1) * dp[i-1]%p;
}
inv[n] = qpow(fac[n], p-2);
for(int i=n;i;--i) inv[i-1] = (ll)inv[i] * i%p; int t = 0;
for(int i=1,j=1;i<=n;i=j) {
while(a[i] == a[j] and j <= n) ++j;
a[++t] = j - i, sum[t] = (a[t] + sum[t-1])%p;
}
n = t; f[1] = dp[a[1]];
for(int i=2;i<=n;++i) {
for(int x = 0; x < a[i]; ++ x)
f[i] = (f[i] + (ll)C(sum[i-1]-1+x,x) * (a[i]-x))%p;
f[i] = (ll)f[i] * f[i-1]%p * dp[a[i]]%p;
}
printf("%d\n", f[n]);
return 0;
}

题解-CSA Beta Round#1 Number Elimination的更多相关文章

  1. Codeforces Beta Round #62 题解【ABCD】

    Codeforces Beta Round #62 A Irrational problem 题意 f(x) = x mod p1 mod p2 mod p3 mod p4 问你[a,b]中有多少个数 ...

  2. Codeforces Beta Round #83 (Div. 1 Only)题解【ABCD】

    Codeforces Beta Round #83 (Div. 1 Only) A. Dorm Water Supply 题意 给你一个n点m边的图,保证每个点的入度和出度最多为1 如果这个点入度为0 ...

  3. Codeforces Beta Round #80 (Div. 2 Only)【ABCD】

    Codeforces Beta Round #80 (Div. 2 Only) A Blackjack1 题意 一共52张扑克,A代表1或者11,2-10表示自己的数字,其他都表示10 现在你已经有一 ...

  4. Codeforces Beta Round #5 B. Center Alignment 模拟题

    B. Center Alignment 题目连接: http://www.codeforces.com/contest/5/problem/B Description Almost every tex ...

  5. Codeforces Beta Round 84 (Div. 2 Only)

    layout: post title: Codeforces Beta Round 84 (Div. 2 Only) author: "luowentaoaa" catalog: ...

  6. Codeforces Beta Round #17 D. Notepad (数论 + 广义欧拉定理降幂)

    Codeforces Beta Round #17 题目链接:点击我打开题目链接 大概题意: 给你 \(b\),\(n\),\(c\). 让你求:\((b)^{n-1}*(b-1)\%c\). \(2 ...

  7. Codeforces Beta Round #16 E. Fish (状压dp)(概率dp)

    Codeforces Beta Round #16 (Div. 2 Only) E. Fish 题目链接:## 点击打开链接 题意: 有 \(n\) 条鱼,每两条鱼相遇都会有其中一只吃掉对方,现在给你 ...

  8. Codeforces Beta Round #13 C. Sequence (DP)

    题目大意 给一个数列,长度不超过 5000,每次可以将其中的一个数加 1 或者减 1,问,最少需要多少次操作,才能使得这个数列单调不降 数列中每个数为 -109-109 中的一个数 做法分析 先这样考 ...

  9. Codeforces Beta Round #79 (Div. 2 Only)

    Codeforces Beta Round #79 (Div. 2 Only) http://codeforces.com/contest/102 A #include<bits/stdc++. ...

随机推荐

  1. Mysql中如何查看慢查询以及查看线程

    一.MySQL数据库有几个配置选项可以帮助我们及时捕获低效SQL语句 1,slow_query_log这个参数设置为ON,可以捕获执行时间超过一定数值的SQL语句. 2,long_query_time ...

  2. 数据库中的union与union all的区别

    Union因为要进行重复值扫描,所以效率低.如果合并没有刻意要删除重复行,那么就使用Union All  两个要联合的SQL语句 字段个数必须一样,而且字段类型要“相容”(一致): 如果我们需要将两个 ...

  3. Tosca : 把 inner text 放到变量里,定义变量,使用变量

    XB的是分开取 注意颜色要变成蓝色的,才可用 上面是定义 下面是使用 键盘输入变量

  4. Docs-.NET-C#-指南-语言参考-关键字-值类型:char

    ylbtech-Docs-.NET-C#-指南-语言参考-关键字-值类型:char 1.返回顶部 1. char(C# 参考) 2019/10/22 char 类型关键字是 .NET System.C ...

  5. openresty开发系列1--网关API架构及选型

    微服务架构在项目中的应用越来越多,我们知道在微服务架构风格中,一个大应用被拆分成为了多个小的服务系统提供出来,这些小的系统他们可以自成体系,也就是说这些小系统可以拥有自己的数据库,框架甚至语言等,这些 ...

  6. shell编程系列2--字符串的处理

    shell编程系列2--字符串的处理 字符串的处理 .计算字符串的长度 方法1 ${#string} 方法2 expr length "$string" (如果string中间有空 ...

  7. linux非root用户安装jdk1.8

    如题,先到 Oracle 官方网站 下载1.8版本的 JDK 压缩包(jdk-8u221-linux-x64.tar.gz)到本地(如D盘的soft目录),然后开始进入linux的非root用户(如w ...

  8. Qt编写自定义控件70-扁平化flatui

    一.前言 对于现在做前端开发人员来说,FlatUI肯定不陌生,最近几年扁平化的设计越来越流行,大概由于现在PC端和移动端的设备的分辨率越来越高,扁平化反而看起来更让人愉悦,而通过渐变色产生的质感色彩反 ...

  9. 【JS新手教程】replace替换一个字符串中所有的某单词

    JS中的replace方法可以替换一个字符串中的单词.语句的格式是: 需要改的字符串.replace(字符串或正则表达式,替换成的字符串) 如果第一个参数用字符串,默认是找到该字符串中的第一个匹配的字 ...

  10. 微信API V3 RESTFUL

    {"code":"SIGN_ERROR","message":"商户未设置加密的密钥,请登录商户平台操作!请参考http://kf ...