C. Permutation Partitions

传送门:https://codeforces.ml/contest/1326/problem/C

题意:  

  给你一个长度为n的序列,要求分成k份,使每一份中的max值和最大,输出最大的和和分组的方法数。

思路:

  和一定就是最大的k个数的和了,那么难点就在分法,设前k大的数分别为a1,a2,...ak,他们的位置分别为x1,x2,...xk。此问题可以看成插板问题,板可以插在前k大的数字的后面到下一个数字前,那么每一对的位置则为xi+1-xi,然后乘起来就是答案了。

ac代码:

优先队列(我为什么要想得那么复杂啊我去)

 1 #include<iostream>
 2 #include<queue>
 3 using namespace std;
 4 const int mod=998244353;
 5 const int maxn=2e5+5;
 6 typedef long long ll;
 7 ll maxx,ans=1,num;
 8 int n,k;
 9 struct node{
10     int x,pos;
11 }a[maxn];
12 bool operator < (node a,node b){
13     return a.x<b.x;
14 }
15 priority_queue <node> Q;
16  
17 struct node2{
18     int x,pos;
19 }b[maxn];
20 bool operator < (node2 a,node2 b){
21     return a.pos>b.pos;
22 }
23 priority_queue <node2> Q2;
24  
25  
26  
27 int main(){
28     cin>>n>>k;
29     for(int i=1;i<=n;i++){
30         cin>>a[i].x;
31         a[i].pos=i;
32         Q.push(a[i]);
33     }
34     for(int i=1;i<=k;i++){
35         node now=Q.top();
36         Q.pop();
37         maxx+=now.x;
38         node2 cao;
39         cao.x=now.x;
40         cao.pos=now.pos;
41         Q2.push(cao);
42     }
43     node2 caoni=Q2.top();
44     Q2.pop();
45     int last=caoni.pos;
46     for(int i=2;i<=k;i++){
47         node2 now=Q2.top();
48         Q2.pop();
49         ans=(ans*(now.pos-last))%mod;
50         //cout<<" "<<now.pos-last-1<<endl;
51         last=now.pos;
52         //cout<<"*"<<now.pos<<endl;
53     }
54     //cout<<"***"<<ans<<endl;
55     cout<<maxx<<" "<<ans;
56     return 0;
57 }
View Code

简简单单法:

#include<iostream>
using namespace std;
typedef long long ll;
const int mod=998244353;
int n,k,x;
ll ans=1,sum,p=-1;
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>x;
        if(x>=(n-k+1)){
            sum+=x;
            if(p!=-1){
                ans=ans*(i-p)%mod;
            }
            p=i;
        }
    }
    cout<<sum<<" "<<ans;
    return 0;
} 
View Code

 

posted @ 2020-03-20 16:30  艾尔夏尔-Layton  阅读(411)  评论(1编辑  收藏  举报