掌握了java,Collections.sort(),第一个参.compare(第二个参) 是按从小到大。
另外,如果需要用到单调队列,java的TreeSet不能满足(因为去重),那么需要每次加入数,都进行重排。实际上单调队列也是如此,只不过b树效率更高。
题意
https://atcoder.jp/contests/abc116/tasks/abc116_d
n个结构体,每个结构体包含x、y两个参数,问:从中选取k个,res = (x的种类)^2 + y的和,求res最大值。
解法
本题运用贪心,先按y从大到小排序,保证优先考虑到的y最大。
假设让res作为最终选中的结果集。那么x种类第一次出现的数,是可以永久保留在res中,因此它的y大,而且占用一个type。第二次出现的数就有可能被替换出去。
c++
#include<bits/stdc++.h>
using namespace std;
struct node
{
int x,y;
bool operator<(const node&o)const
{
return y>o.y;
}
}a[100005];
int n,k,cot=0;
bool vis[100005];
stack<int>s;
int main()
{
long long ans=0,res=0,type=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
if(cot<k)
{
if(!vis[a[i].x])
{
vis[a[i].x]=true;
type++;
}
else s.push(a[i].y);
res+=a[i].y;
cot++;
ans=max(ans,res+type*type);
}
else
{
if(s.empty())break;
if(vis[a[i].x]) continue;
vis[a[i].x]=true;
type++;
res+=a[i].y;
res-=s.top();s.pop();
ans=max(ans,res+type*type);
}
}
cout<<ans<<endl;
}
java (wa了 找不出原因)
import java.util.*;
public class Main {
static class Struct{
Long x,y;
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt(),k = cin.nextInt();
List<Struct> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
Struct struct = new Struct();
struct.x = cin.nextLong();
struct.y = cin.nextLong();
list.add(struct);
}
Collections.sort(list, new Comparator<Struct>() {
@Override
public int compare(Struct o1, Struct o2) {
return o2.y.compareTo(o1.y);
}
});
int cnt = 0,type = 0;
long ans = 0, res = 0;
Stack<Long> stack = new Stack<>();
Map<Long, Integer> map = new HashMap<>();
for (int i = 0; i <n; i++) {
Struct item = list.get(i);
if (cnt < k) {
if (map.get(item.x) == null) {
//第一次出现
map.put(item.x, 1);
type++;
}else{
//第i>1次出现
stack.push(item.y);
}
res += item.y ;
ans = Math.max(ans, res + type * type);
cnt++;
}else{
// 满了,需要淘汰
if (stack.empty()) {
break;
}
if (map.get(item.x) != null) {
continue;
}
// 新加类型,由于排序了那么前面的肯定更加优先
map.put(item.x, 1);
type++;
res = res - stack.peek() + item.y;
stack.pop();
ans = Math.max(ans, res + type * type);
}
}
System.out.println(ans);
}
}