列表

详情


KS16. 善变的同伴

描述

又到了吃午饭的时间,你和你的同伴刚刚研发出了最新的GSS-483型自动打饭机器人,现在你们正在对机器人进行功能测试。
为了简化问题,我们假设午饭一共有N个菜,对于第i个菜,你和你的同伴对其定义了一个好吃程度(或难吃程度,如果是负数的话……)A[i],
由于一些技(经)术(费)限制,机器人一次只能接受一个指令:两个数L, R——表示机器人将会去打第L~R一共R-L+1个菜。
本着不浪费的原则,你们决定机器人打上来的菜,含着泪也要都吃完,于是你们希望机器人打的菜的好吃程度之和最大
然而,你善变的同伴希望对机器人进行多次测试(实际上可能是为了多吃到好吃的菜),他想知道机器人打M次菜能达到的最大的好吃程度之和
当然,打过一次的菜是不能再打的,而且你也可以对机器人输入-1, -1,表示一个菜也不打

输入描述

第一行:N, M

第二行:A[1], A[2], ..., A[N]

输出描述

一个数字S,表示M次打菜的最大好吃程度之和

示例1

输入:

7 2
1 2 3 -2 3 -10 3

输出:

10

说明:

[1 2 3 -2 3] -10 [3]

示例2

输入:

7 4
1 2 3 -2 3 -10 3

输出:

12

说明:

[1 2 3] -2 [3] -10 [3]

第四次给机器人-1, -1的指令

原站题解

C++ 解法, 执行用时: 4ms, 内存消耗: 528KB, 提交时间: 2021-11-18

/*
 * @Author: your name
 * @Date: 2021-05-30 09:09:13
 * @LastEditTime: 2021-11-17 16:58:58
 * @LastEditors: Please set LastEditors
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: /zhangtao/Main.cpp
 */ 
#include<bits/stdc++.h>
using namespace std;
#define ll long long
// #define int long long
#define _abs(x) ((x)>0?(x):-(x))
const int maxn=150005;
int n,N,m,a[maxn],lst[maxn],nxt[maxn],tot;
ll ans,b[maxn];
inline void del(int i){
    lst[nxt[i]]=lst[i];
    nxt[lst[i]]=nxt[i];
}
struct data_{
    ll x;int id;
    data_ () {}
    data_(ll _x,int _id):x(_x),id(_id) {}
    bool operator<(const data_&b)const{
        return x>b.x;
    }
};
priority_queue<data_> Q;
int main(){
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        if (i==1||(a[i]>0)^(a[i-1]>0)) N++;
        b[N]+=a[i];
    }
    for (int i=1;i<=N;i++){
        lst[i]=i-1;nxt[i]=i+1;
        Q.push(data_(_abs(b[i]),i));
        if (b[i]>0) ans+=b[i],tot++;
    }
    lst[0]=0;nxt[0]=1;lst[N+1]=N;nxt[N+1]=N+1;
    while (tot>m){
        data_ d=Q.top();Q.pop();
        if (lst[nxt[d.id]]!=d.id||nxt[lst[d.id]]!=d.id) continue;
        if (b[d.id]<=0&&(lst[d.id]<1||nxt[d.id]>N)) continue;
        ans-=d.x;tot--;b[d.id]+=b[lst[d.id]]+b[nxt[d.id]];del(lst[d.id]);del(nxt[d.id]);
        Q.push(data_(_abs(b[d.id]),d.id));
    }
    printf("%lld",ans);
    return 0;
}

C++ 解法, 执行用时: 9ms, 内存消耗: 524KB, 提交时间: 2022-04-05

#include <bits/stdc++.h>
#define rep(i,a,b) for (int i=a;i<=b;++i) 
using namespace std;
#define vi vector<int>
const int N = 1e5+5;

int n,m;
int a[N],b[N],dp[2][N],mx[2][N];
int main() {
    cin >> n >> m;
    rep(i,1,n) scanf("%d",a+i);
    int tmp = 0;
    rep(i,1,n) {
        if (a[i] == a[i-1]) b[tmp] += a[i];
        else b[++tmp] = a[i];
    }
    n = tmp;
    memcpy(a,b,sizeof(int)*(n+1));

    //rep(i,1,n) cout << a[i] << ' ';
    //cout << endl;
    int c = 1;
    rep(i,1,n) {
        rep(j,1,min(m,i)) {
            dp[c][j] = max(dp[c^1][j],mx[c^1][j-1])+a[i];
            mx[c][j] = max(mx[c^1][j],dp[c][j]);
        }
        c^=1;
    }
    int ans = 0;
    for (int i=1;i<=min(n,m);++i) ans = max(ans,dp[c^1][i]);
    cout << ans << endl;
    return 0;
}

上一题