• 种树(贪心)(较难)


    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
     
     
     
  • 相关阅读:
    session在.ashx文件操作问题
    最全的CSS浏览器兼容问题
    详解div+css相对定位和绝对定位用法
    CSS前5课总结
    CSS元素定位6-10课
    宽度百分比单位的转换公式
    input点击链接另一个页面,各种操作
    Excel 导入 Sql Server出错——“文本被截断,或者一个或多个字符在目标代码页中没有匹配项”错误的解决
    jQuery:cookie插件的使用
    Jquery.Form和jquery.validate 的使用
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/6014175.html
Copyright © 2020-2023  润新知