zoukankan      html  css  js  c++  java
  • 种树(贪心)(较难)

    2151: 种树

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 714  Solved: 397
    [Submit][Status][Discuss]

    Description

    A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树。园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n。并且每个位置都有一个美观度Ai,如果在这里种树就可以得到这Ai的美观度。但由于A城市土壤肥力欠佳,两棵树决不能种在相邻的位置(i号位置和i+1号位置叫相邻位置。值得注意的是1号和n号也算相邻位置!)。最终市政府给园林部门提供了m棵树苗并要求全部种上,请你帮忙设计种树方案使得美观度总和最大。如果无法将m棵树苗全部种上,给出无解信息。

    Input

    输入的第一行包含两个正整数n、m。第二行n个整数Ai。

    Output

    输出一个整数,表示最佳植树方案可以得到的美观度。如果无解输出“Error!”,不包含引号。

    Sample Input

    【样例输入1】
    7 3
    1 2 3 4 5 6 7
    【样例输入2】
    7 4
    1 2 3 4 5 6 7

    Sample Output

    【样例输出1】
    15

    【样例输出2】
    Error!
    【数据规模】
    对于全部数据:m<=n;
    -1000<=Ai<=1000
    N的大小对于不同数据有所不同:
    数据编号 N的大小 数据编号 N的大小
    1 30 11 200
    2 35 12 2007
    3 40 13 2008
    4 45 14 2009
    5 50 15 2010
    6 55 16 2011
    7 60 17 2012
    8 65 18 199999
    9 200 19 199999
    10 200 20 200000
     
     
    //看了题解,思索了很久才明白,太厉害了。。。
    如果没有必须要隔一个坑种一棵树的条件的话,只许排个序一直选最大的美观值就好了,
    但是有这个条件,还是每次选最大美观值的坑种,直接删除边上两个坑和自己这个坑,就可能有个问题 比如 4 5 4 这样,选了 5 ,但种边上这两点美观度更好,
    所以,非常关键的思路就来了,在你选择这棵坑后,删除边上的两棵,并且把自己的值改为 4+4-5 = 3 ,成为一个新的坑,然后就可以重复进行选最大的美观度的操作了
    如果你后来又选了这个再造坑,说明两边的和大于中间的,这样就能反悔了,剩下的还有一些细节的原因,想清楚并不难。
     
    实现其实也比较难,建立一个二叉最大堆,每次取出最大值,并修改值,并删除边上的坑的值,在维护堆,一个循环取数,ok
    //细节部分写错,wa 很多次。。。
     1 /* ***********************************************
     2 ┆  ┏┓   ┏┓ ┆
     3 ┆┏┛┻━━━┛┻┓ ┆
     4 ┆┃       ┃ ┆
     5 ┆┃   ━   ┃ ┆
     6 ┆┃ ┳┛ ┗┳ ┃ ┆
     7 ┆┃       ┃ ┆
     8 ┆┃   ┻   ┃ ┆
     9 ┆┗━┓ 马 ┏━┛ ┆
    10 ┆  ┃ 勒 ┃  ┆      
    11 ┆  ┃ 戈 ┗━━━┓ ┆
    12 ┆  ┃ 壁     ┣┓┆
    13 ┆  ┃ 的草泥马  ┏┛┆
    14 ┆  ┗┓┓┏━┳┓┏┛ ┆
    15 ┆   ┃┫┫ ┃┫┫ ┆
    16 ┆   ┗┻┛ ┗┻┛ ┆
    17 *************************************************/
    18 
    19 #include <iostream>
    20 #include <stdio.h>
    21 #include <math.h>
    22 using namespace std;
    23 
    24 const int inf = 21e8;
    25 const int maxn= 2e5+2;
    26 
    27 int a[maxn];
    28 int h[maxn];
    29 int pos[maxn];
    30 int l[maxn],r[maxn];
    31 int n,m;
    32 
    33 void up(int u)
    34 {
    35     while (u>1)
    36     {
    37         if (a[h[u]]>a[h[u/2]])
    38         {
    39             swap(h[u],h[u/2]);
    40             swap(pos[h[u]],pos[h[u/2]]);
    41             u/=2;
    42         }
    43         else break;
    44     }
    45 }
    46 
    47 void down(int x)//在堆中的排序的编号
    48 {
    49     int u;
    50     while (x*2<=n)
    51     {
    52         if (a[h[x*2]] > a[h[x*2+1]] || x*2==n) u=x*2;
    53         else u=x*2+1;
    54         if (a[h[x]]<a[h[u]])
    55         {
    56             swap(h[x],h[u]);
    57             swap(pos[h[x]],pos[h[u]]);
    58             x=u;
    59         }
    60         else break;
    61     }
    62 }
    63 
    64 int main()
    65 {
    66     while (scanf("%d%d",&n,&m)!=EOF)
    67     {
    68         int i;
    69         for (i=1;i<=n;i++)
    70         {
    71             scanf("%d",&a[i]);
    72             l[i]=i-1;r[i]=i+1;
    73             h[i]=pos[i]=i;
    74             up(i);
    75         }
    76         l[1]=n;r[n]=1;
    77         if (m>n/2)
    78         {
    79             printf("Error!
    ");
    80             continue;
    81         }
    82         int x,ans=0;
    83         for (i=1;i<=m;i++)
    84         {
    85             x=h[1];
    86             ans+=a[x];
    87             a[x]=a[l[x]]+a[r[x]]-a[x];      //变为一个新的点
    88             a[l[x]]=-inf;down(pos[l[x]]);
    89             a[r[x]]=-inf;down(pos[r[x]]);
    90             down(1);                        //将这个新的点调整位置
    91             l[x]=l[l[x]];r[x]=r[r[x]]; //删除后的左右位置变化
    92             r[l[x]]=x;l[r[x]]=x;
    93         }
    94 
    95         printf("%d
    ",ans);
    96     }
    97     return 0;
    98 }
    View Code
     
     
     
  • 相关阅读:
    Atitit.随时间变色特效 ---包厢管理系统的规划
    Atitit.request http乱码的设计防止 检测与解决最近实践p825 attilax总结.doc
    Atitit.request http乱码的设计防止 检测与解决最近实践p825 attilax总结.doc
    atitit.薄伽梵歌overview  attilax 读后感
    Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称
    Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称
    atitit.薄伽梵歌overview  attilax 读后感
    Atitit 《摩奴法典》overivew 读后感 不是由国王 颁布的,而是 僧侣编制
    Atitit 《摩奴法典》overivew 读后感 不是由国王 颁布的,而是 僧侣编制
    Atitit.执行cli cmd的原理与调试
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/6014175.html
Copyright © 2011-2022 走看看