链接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; }