zoukankan      html  css  js  c++  java
  • 题解 CF1188C 【Array Beauty】

    考虑对美丽值进行 (DP) 来统计答案,发现直接统计美丽值等于 (v) 的子序列方案数不好统计,不妨统计美丽值大于等于 (v) 的方案数。发现这样统计,美丽值为 (v) 的一个子序列在区间 ([1,v]) 都会有贡献,所以这样的合法子序列的方案数即为答案。

    先对 (a) 进行排序,由抽屉原理得美丽值的最大值为 (frac{a_n}{k-1})。枚举当前考虑的美丽值为 (v),设 (f_{i,j}) 为考虑了前 (i) 个数,选了 (j) 个数的合法子序列方案数,得:

    [f_{i,j} = f_{i-1,j} + f_{pos,j-1} ]

    其中 (pos) 为最后一个满足 (a_i - a_{pos} geqslant v) 的位置,转移时只用考虑 (pos) 的贡献,因为之前的合法位置的贡献已经统计到 (pos) 了。因为满足单调性,所以求 (pos) 用双指针即可。

    #include<bits/stdc++.h>
    #define maxn 1010
    #define p 998244353
    using namespace std;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    int n,k,ans;
    int a[maxn],f[maxn][maxn];
    int calc(int v)
    {
        int pos=0;
        for(int i=1;i<=n;++i)
        {
            f[i][0]=1;
            while(a[i]-a[pos+1]>=v) pos++;
            for(int j=1;j<=k;++j)
                f[i][j]=(f[i-1][j]+f[pos][j-1])%p;
        }
        return f[n][k];
    }
    int main()
    {
        read(n),read(k),f[0][0]=1;
        for(int i=1;i<=n;++i) read(a[i]);
        sort(a+1,a+n+1);
        for(int i=1;i<=a[n]/(k-1);++i) ans=(ans+calc(i))%p;
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    [Android Pro] Android源码编译之Nexus5真机编译
    [设计模式] 策略模式(Strategy)
    [Android] Anreoid repo 切换分支
    [Android] repo 下载Android源码(国内镜像)
    [Android] osx下如何使用SublimeText阅读Android系统源码
    [Ubuntu] ubuntu的tty下挂载移动硬盘拷贝数据
    Elasticsearch
    Flink简介
    SQL中instr和like的使用区别
    count(1) 与 count(*) 比较
  • 原文地址:https://www.cnblogs.com/lhm-/p/13471248.html
Copyright © 2011-2022 走看看