题解: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 一场空,__________________。


浙公网安备 33010602011771号