This is the hard version of the problem. The only difference is that in this version n≤200000. You can make hacks only if both versions of the problem are solved.
There are n potions in a line, with potion 1 on the far left and potion n on the far right. Each potion will increase your health by ai when drunk. ai can be negative, meaning that potion will decrease will health.
You start with 0 health and you will walk from left to right, from first potion to the last one. At each potion, you may choose to drink it or ignore it. You must ensure that your health is always non-negative.
What is the largest number of potions you can drink?
input:
The first line contains a single integer n (1≤n≤200000) — the number of potions.
The next line contains n integers a1, a2, ... ,an (−109≤ai≤109) which represent the change in health after drinking that potion.
output:
Output a single integer, the maximum number of potions you can drink without your health becoming negative.
题目意思就是说,给你n杯水,每个水可以是负或正,初始生命值为0,你要保证在自己生命值>0时,和尽可能多杯水,问:最多能和多少水?
乍一看像动态规划,其实不是,用的是贪心,我们尽可能的喝水,如果喝了后生命值为负,我们就吐出我们喝过的最小的水,再继续前行。(为什么吐出喝过最小的水,我们的生命值就一定>=0呢?假设我们喝了第i瓶水后生命值<0,那么我们将这瓶水吐出就一定可以让自己的生命值>=0,如果还有比这杯水更小的水,那么吐出后我们的生命值必>0);还有就是范围相对较大,可能溢出,用long存储一下当前的生命值;数组长度较大,想快速找到我们喝过的最小水,可以用优先队列,就是堆。
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;
public class demo1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n + 1];
for(int i = 1; i <= n; i++) arr[i] = sc.nextInt();
PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
long sum = 0, counter = 0;
for (int i = 1; i <= n; i++) {
sum += arr[i];
pq.add(arr[i]);
counter ++;
if(sum < 0) {
sum -= pq.poll();
counter --;
}
}
System.out.println(counter);
}
}
想明白就不难了,但是难想。还得多做题吧
c++读取二位字符数组:
我们采取的是一个字符一个字符的读,当然用cin >> s[i]也可以;一个字符一个字符读用scanf不行,用cin行:
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
cin >> t[i][j];
}
}
学校的比赛更偏向脑筋急转弯,就是多做题吧。