• 【贪心】【CF1061B】 Views Matter


    Description

    给定一个只有一行的,由 (n) 组小正方体组成的方块,每组是由 (a_i) 块小正方体竖直堆叠起来的,求最多能抽掉多少块使得它的左视图和俯视图不变。方块不会掉落

    Input

    第一行是两个整数 (n~,~m),代表方块组数和另一个没什么卵用的参数。

    下面一行 (n) 个数字,代表 (a_i)

    Output

    一行一个数字代表答案

    Hint

    (1~leq~n~leq~10^5,1~leq~a_i~leq~10^9)

    Solution

    考虑因为只有一行同时要求俯视图不变,所以等价于要求每组上都必须留至少一个小正方体。再考虑左视图,相当于每个高度上都至少有一个。于是我们发现原来每组间的顺序是无所谓的,于是我们将他们按照高度排序。

    现在我们考虑相邻两个,我们设右侧的一组 (B) 较高,左侧的一组 (A) 较低,则显然需要用 (B) 和它右侧的正方体组填充满 (A)(B) 之间高度差的一块。在这一些方块中我们选哪一组进行填充对左视图是没有影响的,但是 (B)(B) 右侧如果有没有被选择过被留下的组,那么它必须在最下面一行被选择从而保证这一组的俯视图不变。如果我们选择这样没被选择的组进行填充,那么它们就不用在最下面一行被选择了,相当于节省了一个方块。所以我们维护扫描到当前位置一共还有多少组没有被选择过,优先选择这一些即可。

    Code

    #include <cstdio>
    #include <algorithm>
    #ifdef ONLINE_JUDGE
    #define freopen(a, b, c)
    #endif
    #define rg register
    #define ci const int
    #define cl const long long
    
    typedef long long int ll;
    
    namespace IPT {
    	const int L = 1000000;
    	char buf[L], *front=buf, *end=buf;
    	char GetChar() {
    		if (front == end) {
    			end = buf + fread(front = buf, 1, L, stdin);
    			if (front == end) return -1;
    		}
    		return *(front++);
    	}
    }
    
    template <typename T>
    inline void qr(T &x) {
    	rg char ch = IPT::GetChar(), lst = ' ';
    	while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
    	while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
    	if (lst == '-') x = -x;
    }
    
    template <typename T>
    inline void ReadDb(T &x) {
    	rg char ch = IPT::GetChar(), lst = ' ';
    	while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
    	while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
    	if (ch == '.') {
    		ch = IPT::GetChar();
    		double base = 1;
    		while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
    	}
    	if (lst == '-') x = -x;
    }
    
    namespace OPT {
    	char buf[120];
    }
    
    template <typename T>
    inline void qw(T x, const char aft, const bool pt) {
    	if (x < 0) {x = -x, putchar('-');}
    	rg int top=0;
    	do {OPT::buf[++top] = x % 10 + '0';} while (x /= 10);
    	while (top) putchar(OPT::buf[top--]);
    	if (pt) putchar(aft);
    }
    
    const int maxn = 100010;
    
    int n, m;
    ll ans;
    int MU[maxn];
    bool vis[maxn];
    
    int main() {
    	freopen("1.in", "r", stdin);
    	qr(n); qr(m);
    	for (rg int i = 1; i <= n; ++i) {
    		qr(MU[i]);
    		ans += MU[i];
    	}
    	std::sort(MU + 1, MU + 1 + n);
    	int pre = 0;
    	for (rg int i = n; i; --i) {
    		++pre;
    		pre -= MU[i] - MU[i - 1];
    		ans -= MU[i] - MU[i - 1];
    		pre = std::max(0, pre);
    	}
    	qw(ans - pre, '
    ', true);
    	return 0;
    }
    
  • 相关阅读:
    抽屉视图第三方控件
    数组NSArry注意事项
    NSInteger 和 NSUInteger 比较大小的注意事项
    IOS应用中的二维码生成和二维码扫描解析
    FMDatabase 的使用(转)
    ASIHTTPRequest的简单使用
    关于MBProgressHUD的使用
    获取文件夹大小
    31. Next Permutation(中等,搞清楚啥是 next permutation)
    Deap Learning (吴恩达) 第一章深度学习概论 学习笔记
  • 原文地址:https://www.cnblogs.com/yifusuyi/p/10212991.html
Copyright © 2020-2023  润新知