题解:P14057 【MX-X21-T2】[IAMOI R5] 空气蛹
weifengzhaomi · · 题解
其实本来我做出来第一题就不想做第二题了,同学强迫我做的。
思路
这道题一眼贪心。
那么怎么贪呢。
我们通过
证明很好证,比如说有一个空杯子,那么我们排序时向前排,就能把前面比他小的数字放到空杯子,然后当前的数字向前移,再把替换的数放到空出来的位置。
那么,我们发现,那如果直接进行排序肯定没有腾出一个空杯子更优。
于是,我们对原数组排序,合并两个水最少的杯子,腾出位置,这样子可以做到最小损失。
然后,我们在进行求和。
但是,完了吗?
我们发现,这样子我们还是只有
我们看个例子:
10 100
100 100 100 100 100 100 100 100 100 100
应该输出1000,但我们的代码输出900。
这说明我们的代码对于数组本身就是排好序时且数字为
那么,统一一下,如果数组本身有序,直接输出整个数组的和即可。
那么,我们在一开始的代码判断一下序列是不是有序的就行了。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t,n,m,ans,a[200000];
inline bool clec(){
for (int i = 1;i < n;i++) if (a[i] > a[i + 1]) return false;
return true;
}
signed main(){
cin >> t; while (t--){
cin >> n >> m,ans = 0;
for (int i = 1;i <= n;i++) cin >> a[i];
if (clec()){
for (int i = 1;i <= n;i++) ans += a[i];
cout << ans << endl;
continue;
}
sort(a + 1,a + n + 1);
a[2] += a[1];
a[1] = 0;
if (a[2] > m) a[2] = m;
for (int i = 1;i <= n;i++) ans += a[i];
cout << ans << endl;
}
}