P3143 [USACO16OPEN]鉆石收藏家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 NNN diamonds (N≤50,000N \leq 50,000N≤50,000) of varying sizes, and she wants to arrange some of them in a pair of display cases in the barn.
Since Bessie wants the diamonds in each of the two cases to 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 KKK (two diamonds can be displayed together in the same case if their sizes differ by exactly KKK). Given KKK, please help Bessie determine the maximum number of diamonds she can display in both cases together.
奶牛Bessie很喜歡閃亮亮的東西(Baling~Baling~),所以她喜歡在她的空余時間開采鉆石!她現在已經收集了N顆不同大小的鉆石(N<=50,000),現在她想在谷倉的兩個陳列架上擺放一些鉆石。
Bessie想讓這些陳列架上的鉆石保持相似的大小,所以她不會把兩個大小相差K以上的鉆石同時放在一個陳列架上(如果兩顆鉆石的大小差值為K,那麽它們可以同時放在一個陳列架上)。現在給出K,請你幫Bessie確定她最多一共可以放多少顆鉆石在這兩個陳列架上。
輸入輸出格式
輸入格式:The first line of the input file contains NNN and KKK (0≤K≤1,000,000,0000 \leq K \leq 1,000,000,0000≤K≤1,000,000,000).
The next NNN lines each contain an integer giving the size of one of the
diamonds. All sizes will be positive and will not exceed 1,000,000,0001,000,000,0001,000,000,000.
輸出格式:Output a single positive integer, telling the maximum number of diamonds that
Bessie can showcase in total in both the cases.
輸入輸出樣例
輸入樣例#1: 復制7 3 10 5 1 12 9 5 14輸出樣例#1: 復制
5
分析題意
題目大意就是要在排好序的數列中找出兩段長度和最大的不重合的區間,並使兩個區間中的最大值與最小值的差不大於k。
有幾種可能的情況,
1.兩個區間相鄰,
2. 兩個區間不相鄰
我開始是找的次大和最大的區間然後加起來,對於第2種情況是對的,但對第1種不對,最大區間拆出來一點再向右擴展可能更優
所以有點dp的意思,枚舉每個點的前面的點結尾放的最大值的加這個點以後的點開始放的最大值,求max
code:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 int a[50001],n,k,ans=0; 6 int l[50001],r[50001]; 7 int main() 8 { 9 scanf("%d%d",&n,&k); 10 for (int i=1;i<=n;++i) scanf("%d",&a[i]); 11 sort(a+1,a+n+1); 12 int h=1; l[1]=1; 13 for (int i=2;i<=n;++i) 14 { 15 while (a[i]-a[h]>k) h++; 16 l[i]=max(l[i-1],i-h+1); 17 } 18 r[n]=1; 19 h=n; 20 for (int i=n-1;i>=1;--i) 21 { 22 while (a[h]-a[i]>k) h--; 23 r[i]=max(r[i+1],h-i+1); 24 } 25 for (int i=1;i<n;++i) 26 ans=max(ans,l[i]+r[i+1]); 27 printf("%d\n",ans); 28 }
P3143 [USACO16OPEN]鉆石收藏家Diamond Collector(伸縮法)