Bzoj 4582 [Usaco2016 Open] Diamond Collector 题解

4582: [Usaco2016 Open]Diamond Collector

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 204  Solved: 136
[Submit][Status][Discuss]

Description

Bessie the cow, always a fan of shiny objects, has taken up a hobby of mining diamonds in her spare

time! She has collected N diamonds (N≤50,000) of varying sizes, and she wants to arrange some of th

em in a pair of display cases in the barn.Since Bessie wants the diamonds in each of the two cases t

o be relatively similar in size, she decides that she will not include two diamonds in the same case

if their sizes differ by more than K (two diamonds can be displayed together in the same case if th

eir sizes differ by exactly K). Given K, please help Bessie determine the maximum number of diamonds

she can display in both cases together.

给定长度为N的数列a,要求选出两个互不相交的子序列(可以不连续),满足同一个子序列中任意两个元素差的绝

对值不超过K。最大化两个子序列长度的和并输出这个值。1 ≤ N ≤ 50000, 1 ≤ a_i ≤ 10 ^ 9, 0 ≤ K ≤ 10^ 9

Input

The first line of the input file contains N and K (0≤K≤1,000,000,000). The next NN lines each cont

ain an integer giving the size of one of the diamonds. All sizes will be positive and will not excee

d 1,000,000,000

Output

Output a single positive integer, telling the maximum number of diamonds that Bessie can showcase in

total in both the cases.

Sample Input

7 3

10

5

1

12

9

5

14

Sample Output

5

HINT

Source

Silver鸣谢frank_c1提供翻译

  这道题当时第一次打打的是一个贪心,先去找最大的满足条件的序列,然后再去找刨去该序列后的最大的序列,虽然可以证明不对,但当时没有多想,对了70%还算比较优秀吧……

  我们可以对答案进行一下分析,首先既然对于顺序无限制我们可以将a排序,这样答案就变成了选择两个不相交的区间,将问题简化。对于答案来说,一定有两个点分别满足他是一个区间的右端点,另一个区间在他的右侧或他是一个区间的左端点,另一个区间在他右侧,所以,我们只需要把每个点向左和向右是否包含他的最大合法区间长度记录下来,然后去枚举每个点作为上述特殊点是答案是多少,直接输出最大值即可。

  

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<vector>
10 #define N 50005
11 using namespace std;
12 int n,l,a[N],f[2][N][2];
13 int main()
14 {
15     scanf("%d%d",&n,&l);
16     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
17     sort(a+1,a+n+1);
18     int la=0;
19     for(int i=1;i<=n;i++)
20     {
21         int t=la;
22         while(a[i]-a[i-t]>l) t--;
23         t++;
24         la=t;
25         f[0][i][0]=t;
26         f[0][i][1]=max(f[0][i-1][0],f[0][i-1][1]);
27     }
28     la=0;
29     for(int i=n;i>0;i--)
30     {
31         int t=la;
32         while(a[i+t]-a[i]>l) t--;
33         t++;
34         la=t;
35         f[1][i][0]=t;
36         f[1][i][1]=max(f[1][i+1][0],f[1][i+1][1]);
37     }
38     int ans=0;
39     for(int i=1;i<=n;i++)
40     {
41         ans=max(ans,max(f[1][i][0]+f[0][i][1],f[0][i][0]+f[1][i][1]));
42     }
43     printf("%d\n",ans);
44     return 0;
45 }

时间: 2024-11-08 10:29:53

Bzoj 4582 [Usaco2016 Open] Diamond Collector 题解的相关文章

BZOJ 4582: [Usaco2016 Open]Diamond Collector

Descrirption 给你一个长度为 \(n\) 的序列,求将它分成两个序列后最多个数,每个序列最大值最小值不能超过 \(k\) Sol 二分+DP. 排一下序,找出以这个点结尾和开始的位置. 这个玩意可以二分也可以用单调队列,随便搞啊... 然后统计答案就是枚举第二个序列的起点,然后往后扫的时候统计一下,第一个序列的最大长度就可以了. Code /************************************************************** Problem:

4582: [Usaco2016 Open]Diamond Collector

4582: [Usaco2016 Open]Diamond Collector Description Bessie the cow, always a fan of shiny objects, has taken up a hobby of mining diamonds in her spare time! She has collected N diamonds (N≤50,000) of varying sizes, and she wants to arrange some of t

bzoj4582[Usaco2016 Open]Diamond Collector

bzoj4582[Usaco2016 Open]Diamond Collector 题意: n个钻石,每个都有一个大小,现在将其装进2个盒子里,每个盒子里的钻石最大的与最小的大小不能超过k,问最多能装多少个.n最大50000. 题解: 我真傻,真的~首先对大小排序,然后找以i为左端点的可装区间,这个操作两个指针就可以搞,我却以为要二分查找.预处理完了,因为不交错的区间肯定比交错的区间优,所以从n到1递推一下从n到i最大的区间大小是多少,然后枚举每个区间,找到当前区间大小加上右端点+1到n中最大的

Luogu P3143 [USACO16OPEN]钻石收藏家Diamond Collector 题解

又是一个学数据结构学傻了的人 才不会承认是看到Splay,觉得可以写平衡树才进来的呢 Description: 给出一个序列,问排序后,选取两个区间,使其没有重合部分,且每个区间右端点减去左端点不大于k,求这两个区间长度之和的最大值. 前置技能:FHQ-Treap.线段树 (不会的出门百度) Solution: 看数据范围,5e4,很好,O(nlogn)完全可以水过去.那么我们可以放心的考虑FHQ了.因为要最优,所以我们要找到每一个点,在有序序列中对应的满足题目条件的区间的大小,这就可以用FHQ

BZOJ 4576: [Usaco2016 Open]262144

Description 一个序列,每次可以将两个相同的数合成一个数,价值+1,求最后最大价值 \(n \leqslant 262144\) Sol DP. 这道题是 BZOJ 4580: [Usaco2016 Open]248 加强版. 做248的那个区间DP其实很多方案都是0,而且一个区间中只有一个合法的数字. 然后就是 一个区间合成一个数的方案的这个数字是固定的. \(f[i][j]\) 表示以 \(i\) 结尾是否能合成 \(j\),同时记录一下转移位置,每次向前找前一个指针就可以了. 复

Diamond Collector (动态规划)

问题 I: Diamond Collector 时间限制: 1 Sec  内存限制: 64 MB提交: 22  解决: 7[提交][状态][讨论版] 题目描述 Bessie the cow, always a fan of shiny objects, has taken up a hobby of mining diamonds in her spare time! She has collected N diamonds (N≤50,000) of varying sizes, and sh

斜率优化专题4——bzoj 1911: [Apio2010] 特别行动队 题解

[原题] 1911: [Apio2010]特别行动队 Time Limit: 4 Sec  Memory Limit: 64 MB Submit: 2134  Solved: 911 [Submit][Status] Description Input Output Sample Input 4 -1 10 -20 2 2 3 4 Sample Output 9 HINT [分析]只要跟着我前面的题目走,这道题真的是太水了.神马题解都不用参考,公式随便推. 易知方程是f[i]=max(f[j]+

主席树初探 &amp; bzoj 3295: [Cqoi2011] 动态逆序对 题解

[原题] 3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 778  Solved: 263 [Submit][Status] Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数. Input 输入第一行包含两个整数n和m,即初始元素的个数和删除的元

Diamond Collector

Diamond Collector 题目描述 Bessie the cow, always a fan of shiny objects, has taken up a hobby of mining diamonds in her spare time! She has collected N diamonds (N≤50,000) of varying sizes, and she wants to arrange some of them in a pair of display case