CF 1006B Polycarp's Practice【贪心】

本文针对一个具体的算法竞赛题目,详细解析了如何通过寻找数组中最大值并合理分配区间来达到区间最大值之和的最大化。文章提供了一种有效的解决方案,并附带了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Polycarp is practicing his problem solving skill. He has a list of n problems with difficulties a1,a2,…,an, respectively. His plan is to practice for exactly k days. Each day he has to solve at least one problem from his list. Polycarp solves the problems in the order they are given in his list, he cannot skip any problem from his list. He has to solve all n problems in exactly k days.

Thus, each day Polycarp solves a contiguous sequence of (consecutive) problems from the start of the list. He can't skip problems or solve them multiple times. As a result, in k days he will solve all the n problems.

The profit of the j-th day of Polycarp's practice is the maximum among all the difficulties of problems Polycarp solves during the j-th day (i.e. if he solves problems with indices from l to r during a day, then the profit of the day is maxl≤i≤rai). The total profit of his practice is the sum of the profits over all k days of his practice.

You want to help Polycarp to get the maximum possible total profit over all valid ways to solve problems. Your task is to distribute all n problems between k days satisfying the conditions above in such a way, that the total profit is maximum.

For example, if n=8,k=3 and a=[5,4,2,6,5,1,9,2], one of the possible distributions with maximum total profit is: [5,4,2],[6,5],[1,9,2]. Here the total profit equals 5+6+9=20.

Input
The first line of the input contains two integers n and k (1≤k≤n≤2000) — the number of problems and the number of days, respectively.

The second line of the input contains n integers a1,a2,…,an (1≤ai≤2000) — difficulties of problems in Polycarp's list, in the order they are placed in the list (i.e. in the order Polycarp will solve them).

Output
In the first line of the output print the maximum possible total profit.

In the second line print exactly k positive integers t1,t2,…,tk (t1+t2+⋯+tk must equal n), where tj means the number of problems Polycarp will solve during the j-th day in order to achieve the maximum possible total profit of his practice.

If there are many possible answers, you may print any of them.

Examples
Input
8 3
5 4 2 6 5 1 9 2
Output
20
3 2 3
Input
5 1
1 1 1 1 1
Output
1
5
Input
4 2
1 2000 2000 2
Output
4000
2 2
Note
The first example is described in the problem statement.

In the second example there is only one possible distribution.

In the third example the best answer is to distribute problems in the following way: [1,2000],[2000,2]. The total profit of this distribution is 2000+2000=4000.
【题意】:给定一个数字n和m和大小为n的数组,将数组分为m个区间,要求区间最大值之和最大值以及分区大小(不唯一)。
【分析】:用结构体记录数值和位置,由大到小排序得到前k个数值之和就是最大值。难点是求分区大小,可以建立一个新数组id记录前k大数的位置,注意位置需要从小到大排序。比如第一个样例就是0 3 6,那么分区为3 3 2——>3-0/6-3/8-6
【代码】:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n,m;
struct node
{
    int num,pos;
}a[N];
vector<int> v;
int id[N];
bool cmp(node a,node b)
{
    return a.num > b.num;
}
int main()
{
    scanf("%d%d",&n,&m);
    int ans = 0;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&a[i].num);
        a[i].pos = i;
    }
    sort(a,a+n,cmp);
    for(int i=0; i<m; i++)
    {
        id[i] = a[i].pos;
        ans += a[i].num;
    }
    cout<<ans<<endl;
    id[m]=n;
    sort(id,id+m+1);
    printf("%d ",id[1]);
    for(int i=1; i<m-1; i++)
    {
       printf("%d ",id[i+1]-id[i]);
    }
    if(m!=1) printf("%d\n",id[m]-id[m-1]);
}

转载于:https://www.cnblogs.com/Roni-i/p/9350326.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值