Codeforces 1189F. Array Beauty

Portal

First, there may be noted that the sequence order of the elements of the answer is not affected, so apart from anything else to look at how to sort out

Consider enumerate the contribution of each seed sequence that may arise and to count the contribution of the generated sequence number

Consider setting $ F (x) $ represents the difference is at least the length of the element selected as the number of $ X $ $ k $ subsequence scheme

Not considered complexity, this can obviously be $ DP $, the set $ f [i] [j] $ denotes the length of $ I $, consider the previous $ J $ locations, the first $ J $ position forcedly selected the number of sub-sequences scheme

There then transferred $ f [i] [j] + = f [i-1] [k] $ where $ k <j $ and $ a_j-a_k> = x $ ($ A $ has been noted that at this time in ascending Sort of)

Noted that with the increase of $ j $ and $ k $ lawful must be increasingly large and was a prefix range, it is clear that the transfer can maintain a pointer and a prefix and accelerated to $ O (1) $

Now the complexity of a single $ dp $ is outstanding $ nk $, then think again enumerate $ x $ of complexity, well, the complexity to achieve outstanding $ max (a) nk $

Then noticed a seemingly insignificant optimization: Enumeration if $ x $ when $ x> max (a) / k + 1 $, then certainly there is no legitimate length of the sequence $ k $ (apparently it)

Found complexity becomes $ \ frac {max (a)} {k + 1} nk $ i.e. $ max (a) n $ ...

Then pass by ......

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=1007,mo=998244353;
inline int fk(int x) { return x>=mo ? x-mo : x; }
int n,m,A[N];
int f[N][N],ans;
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++) A[i]=read();
    sort(A+1,A+n+1); int mx=A[n];
    for(int I=1;I<=mx/(m-1);I++)
    {
        for(int i=1;i<=n;i++) f[1][i]=1;
        for(int i=2;i<=m;i++)
        {
            int sum=0,p=1;
            for(int j=1;j<=n;j++)
            {
                while(A[p]+I<=A[j])
                    sum=fk(sum+f[i-1][p++]);
                f[i][j]=sum;
            }
        }
        for(int i=1;i<=n;i++) ans=fk(ans+f[m][i]);
    }
    printf("%d\n",ans);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/LLTYYC/p/11729176.html