题意

给出数列\(a_i\),求排列\(p_i\)的数量满足

\[\frac{a_{p_i}}{max_{j=1}^{i-1}a_{p_j}} \notin (\frac{1}{2},2)
\]

思路

数列可以按前缀最大值相同划分为几个连续段,不妨设第\(i\)段开头(即前缀最大值)为\(m_i\),满足\(2m_i \leq m_{i+1}\),第\(i\)段内元素\(x\)满足\(2x \leq m_i\),

于是有一个\(dp\)做法,\(dp_i\)表示当前段开头为\(a_i\),枚举上一段的开头\(a_j\),将\(a_i\)放在当前的第一个空位中,对于所有\(2a_j \leq a_i\),有序填入剩余空位中。

我们有转移方程

\[dp_i = \sum dp_j\cdot A(n-2-pre_j,pre_i-pre_j-1)
\]

其中\(pre_i\)表示\(2a_j \leq a_i\) 的个数,\(n-2-pre_j\)表示剩余空位,\(-2\)去掉了\(a_i,a_j\),\(pre_i-pre_j-1\)表示当前可用的,\(-1\)去掉了\(a_j\)。

代码

#include<bits/stdc++.h>
#define int long long
#define N 5005
#define mod 998244353
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=n;i>=a;i--)
#define inf 0x3f3f3f3f
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define lowbit(i) ((i)&(-i))
#define VI vector<int>
#define all(x) x.begin(),x.end()
using namespace std;
int qpow(int a,int b){
int res = 1;
while(b){
if(b&1) res = (res*a)%mod;
a = (a*a)%mod;
b >>= 1;
}
return res;
}
int fac[N],inv[N];
int A(int n,int m){
if(n<0 || m<0 || n<m) return 0;
return (fac[n]*inv[n-m])%mod;
}
int n,a[N],pre[N],dp[N];
signed main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
scanf("%lld",&n);
rep(i,1,n) scanf("%lld",&a[i]);
fac[0] = inv[0] = 1;
rep(i,1,n) fac[i] = (fac[i-1]*i)%mod;
rep(i,1,n) inv[i] = (qpow(fac[i],mod-2))%mod;
sort(a+1,a+n+1);
int p = 0;
rep(i,1,n){
while(p+1 < i && a[p+1]*2 <= a[i]) p++;
pre[i] = p;
} dp[0] = 1; pre[0] = -1;
rep(i,1,n){
rep(j,0,pre[i]){
dp[i] = (dp[i]+dp[j]*A(n-pre[j]-2,pre[i]-pre[j]-1)%mod)%mod;
}
}
// rep(i,1,n) printf("%lld ",dp[i]);
// puts("");
if(pre[n] != n-1) puts("0");
else printf("%lld",dp[n]);
return 0;
}

事实上可以前缀和优化做到\(O(n)\)

Codeforces 1437F Emotional Fishermen(思维,dp)的更多相关文章

  1. [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)

    [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...

  2. 题解-CF1437F Emotional Fishermen

    题面 CF1437F Emotional Fishermen 给 \(n\) 个数的序列 \(a_i\),求有多少种 \(n\) 个数的排列 \(p_i\),使得 \[\frac{a_{p_i}}{\ ...

  3. Educational Codeforces Round 61 F 思维 + 区间dp

    https://codeforces.com/contest/1132/problem/F 思维 + 区间dp 题意 给一个长度为n的字符串(<=500),每次选择消去字符,连续相同的字符可以同 ...

  4. Codeforces Round #533 (Div. 2) C.思维dp D. 多源BFS

    题目链接:https://codeforces.com/contest/1105 C. Ayoub and Lost Array 题目大意:一个长度为n的数组,数组的元素都在[L,R]之间,并且数组全 ...

  5. Queue CodeForces - 353D (思维dp)

    https://codeforces.com/problemset/problem/353/D 大意:给定字符串, 每一秒, 若F在M的右侧, 则交换M与F, 求多少秒后F全在M左侧 $dp[i]$为 ...

  6. codeforces 822 C. Hacker, pack your bags!(思维+dp)

    题目链接:http://codeforces.com/contest/822/submission/28248100 题解:多维的可以先降一下维度sort一下可以而且这种区间类型的可以拆一下区间只要加 ...

  7. codeforces 233 D. Table(思维+dp )

    题目链接:http://codeforces.com/contest/233/problem/D 题意:问在n*m的矩阵中满足在每一个n*n的矩阵里画k个点,一共有几种画法. 题解:其实这题挺简单的但 ...

  8. codeforces 808 E. Selling Souvenirs (dp+二分+思维)

    题目链接:http://codeforces.com/contest/808/problem/E 题意:最多有100000个物品最大能放下300000的背包,每个物品都有权值和重量,为能够带的最大权值 ...

  9. codeforces 572 D. Minimization(dp+ 思维)

    题目链接:http://codeforces.com/contest/572/problem/D 题意:给出一个序列,可以任意调整序列的顺序,使得给出的式子的值最小 题解:显然要先排一下序,然后取相邻 ...

随机推荐

  1. 面试常问:Mybatis使用了哪些设计模式?

    前言 虽然我们都知道有26个设计模式,但是大多停留在概念层面,真实开发中很少遇到,Mybatis源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,能够更深入的理解设计模式. Mybati ...

  2. Keras使用多个GPU并行

    model = Model(inputs=[v_i, v_j], outputs=output_list) model = multi_gpu_model(model,4) model.compile ...

  3. 686. Repeated String Match判断字符串重复几次可以包含另外一个

    public static int repeatedStringMatch(String A, String B) { //判断字符串a重复几次可以包含另外一个字符串b,就是不断叠加字符串a直到长度大 ...

  4. [leetcode]138. Copy List with Random Pointer复制带有随机指针的链表

    public RandomListNode copyRandomList(RandomListNode head) { /* 深复制,就是不能只是复制原链表变量,而是做一个和原来链表一模一样的新链表, ...

  5. stm32学习笔记之SysTick的思考

    原文来自--SevenZ的笔记.http://blog.21ic.com/user1/8247/archives/2011/85920.html ? 首先我们要明白什么是SysTick定时器? Sys ...

  6. lua脚本简介

    Lua [1]  是一个小巧的脚本语言.它是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个由Roberto Ier ...

  7. 入门oj 6492: 小B的询问

    Description 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L ...

  8. java线程,进程,多线程

    (1)线程和进程 通俗一点,进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行. (2)java中实现线程的两种方式,第一种是继承Thre ...

  9. slice,splice,split,unshift的用法

    工作了很久始终对这4个用法处于混淆状态,今天写个帖子来警示下自己 // slice(start,end),从start值开始截取到end前的元素组成新的数组,不改变原数组 // slice(index ...

  10. 如何不使用 overflow: hidden 实现 overflow: hidden

    一个很有意思的题目.如何不使用 overflow: hidden 实现 overflow: hidden? CSS 中 overflow 定义当一个元素的内容太大而无法适应块级格式化上下文时候该做什么 ...