"EZEC-5" people win

Insert picture description here
Insert picture description here
Input:
Example 1
3
3 2 1

Example 2
5
3 4 5 4 3

Output:
Example 1
6

Sample 2
28

Idea: Core: Greedy / Monotonic Stack

First analyze the meaning of the question, find the maximum value, and make k * (x+y) as large as possible.
For x==y, we can enumerate the special judgment when inputting data.
If x!=y is left, let’s set kx <ky. For kx, the k value of y is no longer useful. In k * (x+y), k and x have been set. Let y be as far as possible The subscript is bigger.

Method 1: Sort + Greedy O (nlogn)
First sort by k value from largest to smallest, and set the value of k as x first (default kx<ky), because the larger the k, the less y can be selected (because the y is selected) To satisfy ky> kx), just enumerate the satisfied y, and then update the answer while updating the maximum value of y.
Say it is enumerated y, in fact, it only needs to keep the largest subscript y.

Method 2: Monotonic stack maintenance k O(n)
ps: There is an enhanced version of this question. You can only use O(n) to pass
the input and save. Because it is a sequential input, the later subscripts must be larger and put on the stack. Top, the monotonically decreasing stack maintains the ky value from small to large, and the top ky of the stack is less than the current kx, so the maximum y of kx (that is, the maximum subscript is taken at the top of the stack because of sequential input).
The specific operation of maintaining the monotonic stack is as follows:
set the read element as y, and the unread or reading element as x. When kx <ky, directly push the stack and update the answer. When kx ≥ ky, update the answer while simultaneously updating the answer. Unstack elements with ky ≤ kx. After the last unstack, maintain the maximum value with the elements in the stack.

Method 1: Greedy + Sort

//贪心
#include<bits/stdc++.h>
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
using namespace std;
typedef long long ll;
const int N=1e6+10;

struct ty
{
    
    
    int id;//下标
    int k;//权值
}a[N];
bool cmp(ty a,ty b)//按照k值排序
{
    
    
    if( a.k!= b.k ) return a.k>b.k;
    return a.id > b.id;
}
int main()
{
    
    
    int n;
    ll ans=0;
    scanf("%d",&n);

    _for(i,1,n)
    {
    
    
    scanf("%d", &a[i].k);
    a[i].id = i;
    ans = max( ans, 1ll * a[i].k * i);
    }
    sort( a+1 ,a+1+n, cmp);
    int maxn=0;//最大下标
    for(int i=1 ;i<=n ;i++)
    {
    
    
        //更新答案
        ans = max(ans ,1ll * (a[i].id + maxn) * a[i].k );
        maxn = max( maxn, a[i].id );//维护最大下标
    }
    printf("%lld\n",ans);
    return 0;
}

Method 2: Monotonic Stack

//单调栈
#include<bits/stdc++.h>
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
using namespace std;

typedef long long ll;
const int N=1e6+10;

int a[N];
vector <int> st[2]; //0值 1下标
int main()
{
    
    
    int n;
    ll ans=0;
    scanf("%d",&n);

    _for(i,1,n)
    {
    
    
    scanf("%d", &a[i]);
    ans = max( ans, 1ll * a[i] * i);
    }
    //单调栈维护k
    //栈顶下标必定最大,栈里维护k递减且栈顶k小于当前k
    _for(i,1,n)
    {
    
    
        while(  !st[0].empty() && a[i]>=st[0].back() )
        {
    
    
            int x = st[0].back();
            int y = st[1].back();
            ans = max( ans ,1ll* x * (y+i) );
            st[0].pop_back();
            st[1].pop_back();
        }

        if( !st[0].empty())
        {
    
    
            int x = st[0].back();
            int y = st[1].back();
            ans = max( ans ,1ll* a[i] * (y+i) );
        }
        st[0].push_back(a[i]);
        st[1].push_back(i);
    }
    printf("%lld\n",ans);
}

Guess you like

Origin blog.csdn.net/m0_53688600/article/details/114960273
win