牛客練習賽29-A——可持久化動態圖上樹狀陣列維護01揹包(貪心)
阿新 • • 發佈:2018-12-11
題目描述
你有一個長度為 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); }