标签:hose appear 二分 操作 必须 record beautiful fir nsis
Star
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 516 Accepted Submission(s): 213
Problem Description
One of Resty‘s interests is to watch stars. The Stars are so beautiful! Lyra‘s Vega, Alpha Aquila - Altair and Alpha Cyg consist of the Summer Triangle. Resty likes them very much.
One day, Resty comes to the Moon to have his picnic. Soon he found that he can see so many beautiful stars here! You can never find such a view again - All the beautiful stars are in one line!! So Resty wants to take photos to record the incredible moment.
Resty likes those stars so much so he knows which one is more beautiful. Now he gives each star a score, (a number between 1 and 200000, the higher, the better). So we can use an integer sequence to show the stars from left to right.
Resty‘s camera is very strange and it will take two photos at one time, and each photo will contain a series of continuous stars in it. No stars will appear in both photos, and even no two stars that adjacent to each other will be in different photos. The number of stars in each photo will between x and y.
Now, Resty tells you the sequence, you must find two photos that the average score of all the stars in the photos is as great as possible.
Input
The input consists of more than one test case.
Process to the END OF DATA.
For each test case:
The first line contains 3 integers: n, x, y. n is the number of stars.
1 <= x < y <= n <=50000
The second line contains n integers (between 1 and 200000), the score of each stars.
Output
You must output the max average score Resty could get with the precision to 3 digits after the decimal point.
Output Format is "Case ID: ANS" one line for each data
Don‘t print any empty line to the output
Sample Input
5 1 2
1 2 3 4 5
6 2 3
6 1 2 4 3 5
Sample Output
Case 1: 4.000
Case 2: 3.800
Author
Resty
Source
感觉很不错的一道题。
题意: 从一个序列中找出两个不相邻的连续子序列(且每个子序列的长度必须在[x,y]内),使得两个序列内的数的平均值最大化。
做法: 二分这个最大值,判定的时候发现这个式子 (s1+s2)/(l1+l2)>=p , s1,s2为两个序列的总和,l1,l2为长度。转移一下发现
就是让序列中的每个数都减去p之后总和仍>=0,想到这就ok了,我们预处理一下数组。然后计算l[i],r[i], l[i]表示在i之前的满足长度条件的序列的最大值,r[i]同理。然后枚举中间点,只要最大值不小于零表示当前的p可行。
计算l,r时用到了队列优化操作。
用到了优先队列1s+,但是可以用单调队列优化,明天试试^-^。
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define inf 0x3f3f3f3f
4 #define eps 1e-6
5 int a[50010];
6 double b[50010],fl[50010],fr[50010];
7 int n,x,y;
8 struct node{
9 int id;
10 double s;
11 bool operator< (const node& tmp)const{
12 return s>tmp.s;
13 }
14 };
15 bool ok(double p){
16 for(int i=1;i<=n;++i){
17 b[i]=b[i-1]+(double)a[i]-p;
18 }
19 b[n+1]=b[n];
20 priority_queue<node>q;
21 fl[0]=-inf;
22 fr[n+1]=-inf;
23
24
25 for(int i=1;i<=n;++i){
26 if(i-x>=0) q.push(node{i-x,b[i-x]});
27 fl[i]=fl[i-1];
28 while(!q.empty() && i-q.top().id>y) q.pop();
29 if(!q.empty()){
30 fl[i]=max(fl[i],b[i]-b[q.top().id]);
31 }
32 }
33 while(!q.empty())q.pop();
34 for(int i=n;i>=1;--i){
35 if(i+x<=n+1) q.push(node{i+x,b[n]-b[i+x-1]});
36 fr[i]=fr[i+1];
37 while(!q.empty() && q.top().id-i>y) q.pop();
38 if(!q.empty()){
39 fr[i]=max(fr[i],b[n]-b[i-1]-q.top().s);
40 }
41 //cout<<"fr="<<fr[i]<<endl;
42 }
43 double res=-inf;
44 for(int i=1;i<=n;++i){
45 res=max(res,fl[i-1]+fr[i+1]);
46 }
47 return res>=0;
48 }
49 int main(){
50 int i,j,k,cas=0;
51 while(cin>>n>>x>>y){
52 for(i=1;i<=n;++i) scanf("%d",a+i);
53 double l=1,r=200000;
54 while(fabs(l-r)>eps){
55 double mid=(l+r)/2;
56 if(ok(mid)) l=mid;
57 else r=mid;
58 }
59 printf("Case %d: %.3f\n",++cas,l);
60 }
61 return 0;
62 }
hdu-3276-dp+二分+单调队列
标签:hose appear 二分 操作 必须 record beautiful fir nsis
原文地址:https://www.cnblogs.com/zzqc/p/9302353.html