Codeforces Global Round 7.C. Permutation Partitions

链接http://codeforces.com/contest/1326/problem/C

题目大意

给你一个数组,然后让你对他进行分块,具体是分成k块,然后让每一块最大的数的和最大。

做法

那么直接对数组排序,取前k个元素的和就是分块后的最大和了,问题在于如何求分块方案的数量。

这里只需要将原有数列一字排开。然后维护一个check。每次遇到之前算总和的时候没有取到的元素就++。然后一旦遇到了某个块中最大的元素就把他乘到答案里面去。即这个区间内的可能分组情况。这样算下来就是所有可能的区间了。详情请看代码,如果还不懂请评论,有问必答。

代码

#include<bits/stdc++.h>
using namespace std;
long long a[200005];
long long b[200005];
int mp[200005];
long long mod=998244353;
 
int main(){
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        b[i]=a[i];
    }
        long long ans=0;
    sort(a+1,a+n+1,greater<long long>());
    for(int i=1;i<=k;i++){
            ans+=a[i];
        mp[a[i]]=-1;
    }
 
    long long check=1;
    long long fa=1;
    cout<<ans<<" ";
    int flag=0;
    for(int i=1;i<=n;i++){
        if(mp[b[i]]==-1)flag=1;
        if(flag){
        if(mp[b[i]]!=-1)check++;
        else{
            fa*=check%mod;
            fa=fa%mod;
            check=1;
        }
        }
    }
    cout<<fa%mod<<endl;
    return 0;
}
rush!
原文地址:https://www.cnblogs.com/LH2000/p/12528898.html