• CF1437F Emotional Fishermen


    Pro:
    https://www.luogu.com.cn/problem/CF1437F
    有n个渔民,每个渔民钓了一条重(a_i)的鱼
    渔民按任意顺序展示他们的鱼。
    若当前渔民的鱼的重量为(x),之前展示过的鱼的最大重量(y)
    一个排列满足条件当且仅当对于每个(x),满足(2y≤x)(2x≤y)
    问有多少个排列满足条件,对(998244353)取模
    (n<=1e5)

    Sol:

    这个题的核心想法是dp时每次枚举转移下一个happy的渔夫
    也就是使得当前max变化的渔夫
    把所有数字从小到大排好序后
    按照刚才提到的那个想法转移
    发现任意两个happy的渔夫之间
    一定都是sad的渔夫
    考虑把它们放在什么位置
    从dp的想法来考虑的话可以再记一维当前有多少个sad的渔夫还没有决定位置
    每当放了一个happy的渔夫后考虑在他后面放多少个sad的渔夫
    这样状态(O(n^2)) 转移(O(n)) 总共(O(n^3))

    考虑在枚举下一个happy的渔夫的时候直接给中间的sad的渔夫分配位置
    这个的方案数就是一个n选m排列的形式
    转移的时候直接乘上就可以了
    经过推导
    可以得到这样一个式子

    [ fi=sum_{j=1}^{cnt_i} f_j * frac{(n-2-cnt_j)!}{(n-1-cnt_i)!} ]

    直接暴力dp这个式子的复杂度是(O(n^2))
    做一些简单的数学变化加上前缀和优化即可变为(O(n))

    #include<bits/stdc++.h>
    #define N 220000
    #define db double
    #define ll long long
    #define ldb long double
    #define ull unsigned long long
    using namespace std;
    const int h=3,ki=149,mo=998244353;
    int mod(int x){return (x%mo+mo)%mo;}
    int inc(int x,int k){x+=k;return x<mo?x:x-mo;}
    int dec(int x,int k){x-=k;return x>=0?x:x+mo;}
    int ksm(int x,int k)
    {
    	int ans=1;
    	while(k){if(k&1)ans=1ll*ans*x%mo;k>>=1;x=1ll*x*x%mo;}
    	return ans;
    }
    int inv(int x){return ksm(mod(x),mo-2);}
    int read()
    {
    	char ch=0;int x=0,flag=1;
    	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0',ch=getchar();}
    	return x*flag;
    }
    void write(int x)
    {
    	if(!x)return (void)putchar(48);
    	if(x<0)putchar(45),x=-x;
    	int len=0,p[20];
    	while(x)p[++len]=x%10,x/=10;
    	for(int i=len;i>=1;i--)putchar(p[i]+48);
    }
    const db eps=1e-7,inf=1e9+7,pi=acos(-1);
    db Read(){db x;scanf("%lf",&x);return x;}
    void Write(db x){printf("%lf",x);}
    int fac[N],vac[N];
    void prepare(int n)
    {
    	fac[0]=1;for(int i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%mo;
    	vac[n]=inv(fac[n]);for(int i=n;i>=1;i--)vac[i-1]=1ll*vac[i]*i%mo;
    }
    int a[N],f[N],s[N],dp[N];
    int main()
    {
    	int n=read();
    	for(int i=1;i<=n;i++)a[i]=read();sort(a+1,a+n+1);
    	for(int i=1,j=0;i<=n;i++){while(j!=n&&2*a[j+1]<=a[i])j++;f[i]=j;}
    	if(f[n]!=n-1){printf("0");return 0;}prepare(n);
    	for(int i=1;i<=n;i++)
    	{
    		dp[i]=inc(1ll*fac[n-1]*vac[n-1-f[i]]%mo,1ll*vac[n-1-f[i]]*s[f[i]]%mo);
    		s[i]=inc(s[i-1],(n-2-f[i]>=0)?1ll*fac[n-2-f[i]]*dp[i]%mo:0);
    	}
    	write(dp[n]);
    	return 0;
    }
    
  • 相关阅读:
    angluarjs2项目生成内容合并到asp.net mvc4项目中一起发布
    asp.net core 1.1 升级后,操作mysql出错的解决办法。
    asp.net core 简单部署
    asp.net core 简单部署之FTP配置(CentOS 7.0安装配置Vsftp服务器)
    Angular2中对ASP.NET MVC跨域访问
    js中获取DOM元素
    nodejs中的express框架
    jquery.validate的效验方式
    Asp.net MVC4 下二级联动
    Newtonsoft.Json文件错误
  • 原文地址:https://www.cnblogs.com/Creed-qwq/p/13966771.html
Copyright © 2020-2023  润新知