题目链接:http://codeforces.com/contest/1061/problem/B
题意:输入一个n,m,表示有n行可以放置木块的地方。然后输入 每个位置 i 的木块的高度,高度不会m,然后你可以移任意一块木块,并且这个是无重力的,即使你移走靠下的,上面的木块也不会掉下去。问:最多可以移走多少块,让这些木块的俯视图,和右视图没有变化。
题解:思考一个问题。在无重力环境下,想要让俯视图不变,那么必须保证,每一列都至少需要一个木块,想要右视图不变。那么需要从1到最高木块的这些行中,都必须要一个。那么贪心思路显而易见就是考虑每一行都至少有一个。那么我们只需要从低到高排序,然后依次考虑每行木块的贡献度即可。若之前已经构建高度小于当前木块的高度。那么他必须放置的那个就可以放到之前构造最高的位置+1.即可,要是大于,那么就随意放一个即可。然后统计完必须的个数。拿总个数减一下即是答案。若构造的长度小于最高的,再加上最高木块减构造的最高高度。
那么代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
int n,m;
int a[maxn];
int main(){
scanf("%d%d",&n,&m);
long long sum = 0;
int maxx = -1;
for(int i = 0 ; i < n ; i ++){
scanf("%d",&a[i]);
sum += a[i];
maxx = max(maxx,a[i]);
}
sort(a,a+n);
int maxh = 0;
int ans = 0;
for(int i = 0 ; i < n ; i ++){
if(a[i] > maxh) {
ans ++,maxh++;
}
else {
ans ++;
}
}
if(maxh < maxx)
ans += maxx - maxh;
cout << sum - ans << endl;
}