zoukankan      html  css  js  c++  java
  • CF-div3-611-E. New Year Parties

    思路

    贪心

    考虑最大:
    贪心:扩展越多越好,考虑向前扩展,保持不变,和向后扩展,这三种策略何时使用。
    想到如果前面1个元素没有过,那么给它一个;
    如果当前元素还多(比1大),那么考虑向后给一个。
    注意i边界1~n+1范围都可(第16行代码改成<=n;22行改成i<n时,行不行?感觉可以,待验证)

    考虑最小:
    想到3个凑成一组,第i个与第i+1,第i+2个凑成一组(如果第i个有值的话);
    就好了

    为什么会把第i个与i+1和i+2放到一起;而不是把第i个与第i-1和第i+1个放在一起呢?
    考虑到 贪心策略的正确性,,就是前者:后面的不改前面的值,不影响前面策略。想一想就懂差不多了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 2e5+10;
    int n;
    int a[maxn],b[maxn],x[maxn];
    int maxAns = 0,minAns = 0;
    
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>x[i];
    		a[x[i]]++; //统计数量 
    		b[x[i]]++;
    	}
    	for(int i=1;i<=n+1;i++){ //统计最大值 //这里改成n行不行 
    		if(a[i] == 0) continue;
    		if(a[i-1] == 0){ //贪心:左边没值,为了尽可能大,先向左 
    			a[i]--;
    			a[i-1]++;
    		}
    		if(a[i] > 1){ //贪心:如果当前位置数量比1多,向右走一波无妨 
    			a[i]--;
    			a[i+1]++;
    		}
    	}
    	for(int i=0;i<=n+1;i++) 
    		if(a[i]!=0) maxAns++;
    	int pos = 1;
    	while(pos<=n){
    		//考虑当前点如果有值 
    		//那么pos pos+1 pos+2都可以到达第pos个位置 
    		if(b[pos] != 0){ 
    			b[pos+2] = 0; //pos+2点置为0  表示移动到pos+1点 
    			b[pos+1] = 0; //pos+1点置为0 表示移动到pos+1点 
    			pos+=3;
    			minAns++;
    		}else pos++;
    	}
    	cout<<minAns<<" "<<maxAns;
    	return 0;
    }
    /*
    9
    9 5 7 9 6 4 6 4 8
    */ 
    
  • 相关阅读:
    [HNOI2006]超级英雄
    [CTSC1999]家园
    火星探险问题
    [HNOI2008]GT考试
    [USACO14DEC]后卫马克Guard Mark
    [NOI2018]归程
    [USACO15DEC]最大流Max Flow
    [NOIPlus]斗地主
    [LUOGU] P3128 [USACO15DEC]最大流Max Flow
    [BZOJ] 1878: [SDOI2009]HH的项链
  • 原文地址:https://www.cnblogs.com/fisherss/p/12345958.html
Copyright © 2011-2022 走看看