博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【uoj#22】[UR #1]外星人 组合数学+dp
阅读量:4880 次
发布时间:2019-06-11

本文共 1579 字,大约阅读时间需要 5 分钟。

给你一个长度为 $n$ 的序列 $\{a_i\}$ 和一个数 $x$ ,对于任意一个 $1\sim n$ 的排列 $\{p_i\}$ ,从 $1$ 到 $n$ 依次执行 $x=x\ \text{mod}\ a_{p_i}$ ,最终得到一个数。求所有排列中能够得到的这个数的最大值,以及有多少种排列可以得到这个值。

$n\le 1000$ ,$x\le 5000$ 。


题解

组合数学+dp

由于 $a\ \text{mod}\ b<b$ ,因此每次产生影响(即 $x\ \text{mod}\ a_i\ne x$)的 $a_i$ 一定是递减的。

考虑将所有数从大到小排序处理。当确定了某个要产生影响的模数 $a_i$ ,$(x\ \text{mod}\ a_i,x]$ 中除了 $a_i$ 的数就都可以随便放在 $a_i$ 的后面,因为它们不会产生贡献。

设 $f[i]$ 表示处理完 $(i,+\infty)$ 的数,剩下的数为 $i$ 的方案数。

那么考虑 $f[i]$ ,枚举下一个选择的数 $j$ ,令 $s[i]$ 表示小于等于 $i$ 的数的个数,则有 $f[i\ \text{mod}\ j]=f[i]\times A_{s[i]-1}^{s[i]-1-s[i\ \text{mod}\ j]}=f[i]\times\frac{(s[i]-1)!}{(s[i\ \text{mod}\ j])!}$ 。预处理阶乘及阶乘的逆元即可。

时间复杂度 $O(n^2)$ 。

#include 
#include
#define N 1010#define M 5010#define mod 998244353using namespace std;typedef long long ll;int a[N] , sum[M];ll fac[N] , inv[N] , fin[N] , f[M];int main(){ int n , m = 5000 , x , i , j , mn = m; scanf("%d%d" , &n , &x); for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]) , sum[a[i]] ++ , mn = min(mn , a[i]); for(i = 1 ; i <= m ; i ++ ) sum[i] += sum[i - 1]; fac[0] = fin[0] = fac[1] = inv[1] = fin[1] = 1; for(i = 2 ; i <= n ; i ++ ) { fac[i] = fac[i - 1] * i % mod; inv[i] = (mod - mod / i) * inv[mod % i] % mod; fin[i] = fin[i - 1] * inv[i] % mod; } f[x] = fac[n] * fin[sum[x]] % mod; for(i = m ; i ; i -- ) for(j = 1 ; j <= n ; j ++ ) if(a[j] <= i) f[i % a[j]] = (f[i % a[j]] + f[i] * fac[sum[i] - 1] % mod * fin[sum[i % a[j]]]) % mod; for(i = mn - 1 ; ~i ; i -- ) if(f[i]) break; printf("%d %lld" , i , f[i]); return 0;}

 

转载于:https://www.cnblogs.com/GXZlegend/p/8617946.html

你可能感兴趣的文章
登录验证码demo-java
查看>>
【线程的状态转换图及常见执行情况】
查看>>
Velocity简单语法及VelocityHelper封装
查看>>
【js】走近小程序
查看>>
日常练习 1.0
查看>>
Linux下的Telnet设置方法介绍
查看>>
【mmall】学习Spring要善用Spring的Github
查看>>
css--小白入门篇4
查看>>
node.js的介绍
查看>>
WCF入门(七)——异常处理1
查看>>
VisualStudio Shell简介 — 集成插件
查看>>
php集成环境
查看>>
Ubuntu下的负载均衡Web集群配置
查看>>
Create a site by Google Site - All Free
查看>>
[诈骗]“中国移动”发送诈骗短信,china mobile 是骗子吗?
查看>>
Oracle调整内存超出限制出现ORA-27100: shared memory realm already exists问题解决办法
查看>>
玩转WIN7的MKLINK
查看>>
c# 微信分享-原始代码
查看>>
LA 3713 宇航员分组
查看>>
Recipe 1.11. Checking Whether a String Is Text or Binary(Python Cookbook)
查看>>