1. 程式人生 > >牛客練習賽29-A——可持久化動態圖上樹狀陣列維護01揹包(貪心)

牛客練習賽29-A——可持久化動態圖上樹狀陣列維護01揹包(貪心)

題目連結

題目描述

你有一個長度為 n 序列 {a}(序列下標從1開始) ,每次可以從任意位置 i 花費 ai*i 的代價來把 ai 刪除。

注意,刪除後 ai 後面的數會依次向前補上(下標 -1 ) 。

求把整個序列刪完的最小代價。

輸入描述:

第一行一個整數 n ,第二行 n 個整數代表該序列。

輸出描述:

一行一個整數表示刪完序列的最小代價。

示例1

輸入

複製

2
3 2

輸出

複製

5

備註:

1<=n<=106,|ai|<=107

保證答案在 (-264,264) 範圍內

思路:

序列中有正數和負數,想要刪完序列所花代價最小,就要讓刪正數的代價小,刪負數的代價(絕對值)儘量大

注意有負數(之前寫的這個題沒注意到負數。。。錯的可慘了)

1、正數:ai已確定,就讓下標儘量小

2、負數:讓下標儘量大

想要達成上述,我們就會發現應該先刪除負數,想讓下標儘量大,所以從後往前刪除(若先刪前面的,後面負數的下標會減小)

然後從左向右刪正數(這樣正數的下標就都是1)

 

程式碼:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm> 
#define ll long long
using namespace std;
int main()
{
    int n;
    scanf("%d",&n);
    ll ans=0,x;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&x);
        if(x>0)
        ans+=x;
        else
        ans+=x*i;
    }
    printf("%lld\n",ans);
}