tokitsukaze and Soldier 贪心
程序员文章站
2022-03-21 17:37:38
...
- 分析
解析:先处理更加“宽容”的人(希望士兵团不超过的人数更多的人),那么那些不那么“宽容”的被分配到团中时,比这个人更加“宽容”的人也能分配到团中。那么问题就变成了动态的topK问题了。
首先按 s 排序, 然后以 v 值建立一个小根堆(优先队列)
然后对于当前的 a[i] 先进入队列(注意这一步很重要, 判断完再进队是错的)
【 因为这个点我们可能根本就不需要取, 所以不能弹出多余的元素再入队, 要直接入队】
然后此时判断 a[i].s 跟队列大小, 弹出队里最小的元素
在模拟的过程中不断更新答案即可
- 代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.PriorityQueue;
public class Main {
static int n,len;
static Integer a[],b[];
public static void main(String[] args) throws IOException {
StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();n=(int)in.nval;
long v[]=new long [n];
long []s=new long [n];
PriorityQueue<Long>q=new PriorityQueue<Long>();
long sum=0,max=0;
for(int i=0;i<n;i++) {
in.nextToken();v[i]=(long)in.nval;
in.nextToken();s[i]=(long)in.nval;
}
long tempss,temp;
QuickSort(0,n-1,s,v);//从大到小的快排
for(int i=0;i<n;i++) {
q.add(v[i]);
sum+=v[i];
if(q.size()>s[i]) {
while(q.size()>s[i]) {
sum-=q.poll();
}
}
max=Math.max(max, sum);
}
out.println(max);
out.flush();
}
static void QuickSort(int l,int r,long s[],long v[]) {
int i=l,j=r;
long key=s[r+l>>1],temp=0;
do {
while(s[j]<key) j--;
while(s[i]>key) i++;
if(i<=j) {
temp=s[j];s[j]=s[i];s[i]=temp;
temp=v[j];v[j]=v[i];v[i]=temp;
i++;j--;
}
}while(i<=j);
if(l<j) QuickSort(l,j,s,v);
if(i<r) QuickSort(i,r,s,v);
}
}
推荐阅读