• 6562. 【GDOI2020模拟4.15】楼房搭建(building)


    题目描述

    小 H 是一个建筑师,他接到了一个任务——按照计划图搭建一排楼房。计划图上从左到右
    给出了 n 个非负整数,对于第 i 个数 h i ,它表示在 i 这个位置搭建出来的楼房的高度不能小于h i 。
    小 H 搭建楼房的方式也很特别。在每一时刻,它总可以让相邻的两个楼房分别增高 1 个单
    位和增高 2 个单位。具体地,对于任意的 i(1 ≤ i < n),每一时刻他可以有以下两种搭建的方法:
    1. 让 i 位置上的楼房的高度 +2,同时让 i + 1 位置上的楼房 +1。
    2. 让 i 位置上的楼房的高度 +1,同时让 i + 1 位置上的楼房 +2。
    小 H 想知道最快需要多少时间,搭建出来的这一排楼房才能满足计划图的要求?

    n,hi<=10^6

    题解

    贪心苦手表示很淦

    考虑一个假的贪心:每次对当前的进行+2+1,如果最后剩下一个就+1+2

    这样显然是假的,考虑反悔操作:

    ①+2+1->2*(+1+2),等价于用1的代价把i+1位+3

    ②+3->(+1+2)+(+2+1),等价于用1的代价把i+1位+3(前提是至少有一个+3)

    ②+3->3*(+1+2),等价于用2的代价把i+1位+6(前提是至少有一个+3)

    维护当前可以的最多+3次数,判断一下剩余情况与剩余的奇偶即可

    并不需要考虑+3具体是怎么得到的,如果要拆的话等于把之前的一系列组合操作拆开

    感受一下

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define ll long long
    #define file
    using namespace std;
    
    int n,i,j,k,l,x,X,cnt,sum;
    ll ans;
    
    int main()
    {
    	freopen("building.in","r",stdin);
    	#ifdef file
    	freopen("building.out","w",stdout);
    	#endif
    	
    	scanf("%d",&n);
    	fo(i,1,n)
    	{
    		scanf("%d",&x);x-=X;
    		if (x<=0) {X=cnt=0;continue;}
    		
    		if (cnt*3>=x)
    		X=(x%3==0)?0:(3-x%3),ans+=(x/3)+(x%3>0),cnt=(x/3)*2+(x%3==2);
    		else
    		X=((x-cnt*3)/2)+(x-cnt*3)%2*2,x-=cnt*3,ans+=cnt+(x+1)/2,cnt=cnt*2+x/2;
    	}
    	printf("%lld
    ",ans);
    	
    	fclose(stdin);
    	fclose(stdout);
    	
    	return 0;
    }
    
  • 相关阅读:
    让你爱不释手的图片浮动效果
    Polymer API开发指南 (二)(翻译)
    基于HTML5的拓扑图编辑器(2)
    kbengine开源分布式游戏服务端引擎
    Qunee for HTML5 v1.6新版本发布
    [转载] Link prefetch
    小白学phoneGap《构建跨平台APP:phoneGap移动应用实战》连载三(通过实例来体验生命周期)
    云集,让 web app 像 native app 那样运行(雄起吧,Web 开发者)
    Android设置ToolBar的title文字居中显示
    Task 'assembleXXXDebug' not found in project ':app'.的解决方法
  • 原文地址:https://www.cnblogs.com/gmh77/p/12718508.html
Copyright © 2020-2023  润新知