就(so) 题解

                 就so.in/.out

【背景描述】

  一排 N 个数, 第 i 个数是 Ai , 你要找出 K 个不相邻的数, 使得他们的和最大。

  请求出这个最大和。

【输入格式】

第一行两个整数 N 和 K。

接下来一行 N 个整数, 第 i 个整数表示 Ai 。

【输出格式】

一行一个整数表示最大和, 请注意答案可能会超过 int 范围

【样例输入】

3 2

4 5 3

【样例输出】

7

【数据范围】

对于 20% 的数据, N, K ≤ 20 。

对于 40% 的数据, N, K ≤ 1000 。

对于 60% 的数据, N, K ≤ 10000 。

对于 100% 的数据, N, K ≤ 100000 , 1 ≤ Ai ≤ 1000000000。

solution:

  这题考试打的dp,本来有60结果手贱细节崩了瞬间少了55,~~~~(>_<)~~~~,用一个堆维护所有位置,每次取出最大的,然后把这个位置和两边的位置合并,选择合并之后的位置就相当于取消选择原来的位置,并选择两边的位置再把原来的和两边的在堆里删掉,再把合并之后的加入堆里可以用链表来维护两边的位置,重复K次即可,因为只需要k个数

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<set>
 6 using namespace std;
 7 #define inf ((long long)1<<62)
 8 #define int long long
 9 int read() {
10     int s=0,f=1;
11     char ch=getchar();
12     while(ch>'9'||ch<'0') {
13         if(ch=='-') {
14             f=-1;
15         }
16         ch=getchar();
17     }
18     while(ch>='0'&&ch<='9') {
19         s=(s<<1)+(s<<3)+(ch^48);
20         ch=getchar();
21     }
22     return s*f;
23 }
24 struct node {
25     int ord,num;
26     friend bool operator < (node a,node b) {
27         return (a.num==b.num)?(a.ord>b.ord):(a.num>b.num);
28     }
29 };
30 set <node> qq;
31 int pre[100005],nxt[100005],n,k,val[100005];
32 signed main() {
33     n=read();
34     k=read();
35     for(int i=1,x; i<=n; i++) {
36         x=read();
37         val[i]=x;
38         pre[i]=i-1;
39         nxt[i]=i+1;
40         qq.insert((node) {
41             i,x
42         });
43     }
44     long long ans=0;
45     val[0]=-inf;
46     nxt[n]=0;
47     while(k--) {
48         int i=qq.begin()->ord;
49         qq.erase((node) {
50             i,val[i]
51         });
52         ans+=val[i];
53         val[i]=-val[i];
54         val[i]+=val[pre[i]]+val[nxt[i]];
55         qq.erase((node) {
56             pre[i],val[pre[i]]
57         });
58         qq.erase((node) {
59             nxt[i],val[nxt[i]]
60         });
61         qq.insert((node) {
62             i,val[i]
63         });
64         if(pre[pre[i]]) {
65             nxt[pre[pre[i]]]=i;
66         }
67         if(nxt[nxt[i]]<=n) {
68             pre[nxt[nxt[i]]]=i;
69         }
70         pre[i]=pre[pre[i]];
71         nxt[i]=nxt[nxt[i]];
72     }
73     cout<<ans;
74     return 0;
75 }

 

posted @ 2017-08-07 19:40  Forever_goodboy  阅读(177)  评论(0编辑  收藏  举报