加载中...

题解:AT_abc116_d [ABC116D] Various Sushi

Solution

贪心。

我们发现题目中有两个决定因素,分别是美味程度和种类。

我们发现如果考虑种类会使问题复杂化,而计算时只需要知道有多少种类就可以了。

将价值降序排列,枚举从中选 \(i\) 个种类不同、价值最大的物品,再从剩下 \(k - i\) 个未被选择的物品中选择替换。

具体来说,我们要选择满足以下几点要求的寿司:

  • 此寿司未被选择过;

  • 它要替换的寿司出现了不止一次。

感性理解一下,由于种类的贡献是平方级别的,所以我们肯定要优先考虑种类。在实现上,虽然最开始选择的不是最优解,但我们根据一步步替换可以得出正解。

对于替换的要求,都是为了让种类更多。如果不满足以上条件,种类没有变化,那么根据数组降序排序,美味值肯定会减少。

可能以上表达不清晰。看不懂或者有更好的证明可以私信我。

Code

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 1e5 + 10;

struct Node{
	int t,d;
}a[N];

bool cmp(Node x, Node y){
	return x.d > y.d;
}

long long n, m, x, y, res;
long long t2[N];

int main(){
	cin >> n >> m;
	for (int i = 1; i <= n; i ++ )
		cin >> a[i].t >> a[i].d;
    sort(a + 1, a + n + 1, cmp);
    for (int i = 1; i <= m; i++ ){
        if (!t2[a[i].t]) 
			y++;
        t2[a[i].t]++ ;
        x += a[i].d; 
    }
    res = x + y * y;
	int k = m;
	for(int i = m + 1; i <= n && k; i++){
		if(t2[a[i].t])
			continue;
		t2[a[i].t]++ , x += a[i].d;	
		while (t2[a[k].t] <= 1 && k)
			k--;
		if(!k) break; 
		y++, x -= a[k].d, k--;
		res = max(res, x + y * y);
	}
	cout << res;
	return 0;
}

注意:十年 OI 一场空,__________________。

posted @ 2025-10-06 13:51  碎碎念的女巫  阅读(12)  评论(0)    收藏  举报