zoukankan      html  css  js  c++  java
  • [题解]NKOJ 3102取数(乱搞)

    题目描述

    n个整数组成的一个环,现在要从中取出m个数,取走一个数字就不能取跟它相邻的数字(相邻的数不能同时取)。要求取出的数字的总和尽可能大,问这个最大和是多少? 如果无解,请输出“Error!”

    输入输出格式

    输入格式:

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

    输出格式:

    仅一个整数,表示所求结果。如果无解输出“Error!”,不包含引号。

    输入输出样例

    输入样例#1: 
    7 3 
    1 2 3 4 5 6 7
    输出样例#1: 
    15
    输入样例#2: 
    7 4 
    1 2 3 4 5 6 7
    输出样例#2: 
    Error!
    输入样例#3: 
    8 4
    8 5 6 2 3 4 8 9
    输出样例#3: 
    25

    数据范围 对于全部数据:m<=n;-1000<=Ai<=1000 数据编号 N的大小 数据编号 N的大小
    1 40 11 2013 2 45 12 5000 3 50 13 10000 4 55 14 49999 5 200 15 111111
    6 200 16 148888 7 1000 17 188888 8 2010 18 199999 9 2011 19 199999 10
    2012 20 200000

    思路:这道题第一眼有点像区间dp,但是n最大可达200000,所以肯定不行,我又想过nlogn的倍增+区间dp,但是好想不可做,
    后来翻别人题解发现是优先队列,可以反悔的贪心;优先队列里面存两个值,编号和权值,我们先贪心的选数,但是这样可能是
    错的,所以可以设置一个反悔操作,设l[x]为编号x左边元素的编号,r[x]同理,我们贪心选了x后,更优的方案就只可能不选x
    而选l[x]+r[x],所以把l[x]的值+r[x]的值,再放回去,选一共m次,就是最终的答案.

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<queue> 
     5 using namespace std;
     6 const int maxn=(200000<<1)+10;
     7 int n,m,l[maxn],r[maxn],ans,a[maxn],tot;
     8 bool mark[maxn];
     9 struct node{
    10     int id,v;
    11     bool operator < (const node &a) const
    12     {
    13         return v<a.v;
    14     }
    15 };
    16 priority_queue<node>q;
    17 inline int read()
    18 {
    19     int x=0,f=1;char c=getchar();
    20     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    21     while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    22     return x*f;
    23 }
    24 int main()
    25 {
    26     freopen("choose.in","r",stdin);
    27     freopen("choose.out","w",stdout);
    28     n=read();m=read();
    29     if(m>(n>>1)){printf("Error!
    ");return 0;}
    30     for(int i=1;i<=n;++i)a[i]=read();
    31     for(int i=2;i<n;++i)
    32     {
    33         l[i]=i-1;r[i]=i+1;
    34         node tmp;
    35         tmp.id=i;tmp.v=a[i];
    36         q.push(tmp);
    37     }
    38     node tmp;
    39     tmp.id=1;l[1]=n;r[1]=2;tmp.v=a[1];q.push(tmp);
    40     tmp.id=n;l[n]=n-1;r[n]=1;tmp.v=a[n];q.push(tmp);
    41     tot=n;
    42     for(int i=1;i<=m;++i)
    43     {
    44         tmp=q.top();q.pop();
    45         if(mark[tmp.id]){i--;continue;}
    46         ans+=tmp.v;
    47         node t;
    48         a[++tot]=a[l[tmp.id]]+a[r[tmp.id]]-a[tmp.id];
    49         t.id=tot;t.v=a[tot];
    50         l[tot]=l[l[tmp.id]];r[l[l[tmp.id]]]=tot;
    51         r[tot]=r[r[tmp.id]];l[r[r[tmp.id]]]=tot;
    52         mark[tmp.id]=mark[l[tmp.id]]=mark[r[tmp.id]]=1;
    53         q.push(t);
    54     }
    55     printf("%d
    ",ans);
    56     return 0;
    57 }
  • 相关阅读:
    写一个列表生成式,产生一个公差为11的等差数列
    如果对方网站反爬取,封IP了怎么办?
    为什么会选择redis数据库?
    你是否了解谷歌的无头浏览器?
    遇到的反爬虫策略以及解决方法?
    常见的HTTP方法有哪些?
    遇到反爬机制怎么处理?
    列举网络爬虫所用到的网络数据包,解析包?
    python中的关键字yield有什么作用?
    如下代码输出的是什么?
  • 原文地址:https://www.cnblogs.com/fanyujun/p/9415166.html
Copyright © 2011-2022 走看看