牛客练习赛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);
}

猜你喜欢

转载自blog.csdn.net/qq_42804678/article/details/84073950