3 solutions
-
1
和老钟方法一样
#include<bits/stdc++.h> using namespace std; int n,L; double ans,i[100005],p[100005],j[100005],k[100005]; int main() { scanf("%d%d",&n,&L); double l=0,r=2000,jin=1e-6,mid; for(int c=0;c<n;c++) scanf("%lf",&i[c]); while(r-l>jin){ mid=(l+r)/2; for(int c=0;c<n;c++){ p[c]=i[c]-mid; if(c){ k[c]=max(k[c-1]+p[c],p[c]); j[c]=j[c-1]+p[c]; }else{ j[c]=k[c]=p[c]; } } ans=j[L-1]; for(int c=L;c<n;c++){ double ans1=j[c]-j[c-L+1]+k[c-L+1]; ans=max(ans,ans1); } ans>=0?l=mid:r=mid; } printf("%d",(int)(r*1000)); }
-
0
难以言喻的一题,再一次感觉到了我的愚蠢
#include<iostream> using namespace std; #define MAX 100007 #define INF 0x3f3f3f3f double l=1e5+7,r=0; int n,f; int a[MAX],s[MAX]; bool check(double ave){ double sum1=s[f-1]-ave*(f-1); for(int i=f;i<=n;i++){ double sum2=s[i]-s[i-f]-ave*f; sum1=sum1+a[i]-ave; sum1=max(sum1,sum2); if(sum1>-1e-5)return false; } return true; } double search(double L,double R){ double mid; while(R-L>=1e-5){ mid=(L+R)/2; if(check(mid))R=mid; else L=mid; } return R; } int main(){ ios::sync_with_stdio(false); cin>>n>>f; for(int i=1;i<=n;i++){ cin>>a[i]; if(a[i]>r)r=a[i]; if(a[i]<l)l=a[i]; s[i]=s[i-1]+a[i]; } double ans=search(l,r); cout<<(int)(ans*1000); return 0; }
-
0
https://blog.csdn.net/justidle/article/details/104318076
#include <bits/stdc++.h> using namespace std; const int MAXN = 1e5+2; double data[MAXN] = {};//保存数组A double a[MAXN];//减去枚举值后的数组 double sum[MAXN];//前缀和数组 double maxx[MAXN];// i 为结尾的最大连续区间和 double dp[MAXN];// i 为结尾区间连续长度大于等于 L 的最大连续区间和 int main() { //读入n和l int n,l; scanf("%d%d", &n, &l); //读入数组A int i; double left = 2000;//左边界 double right = 1;//右边界 for (i=1; i<=n; i++) { //注意由于需要使用前缀和,所以第一个数据要设置为0 scanf("%lf", &data[i]); left = min(left, data[i]);//更新左边界 right = max(right, data[i]);//更新右边界 } double eps = 1e-6;//精度 while (right-left > eps) { //计算中间值 double mid = (left+right)/2; //数组A的每个数据减去这个枚举值,并计算前缀和 for (i=1; i<=n; i++) { a[i]=data[i]-mid; sum[i]=sum[i-1]+a[i]; maxx[i] = max(a[i], maxx[i-1]+a[i]); } //遍历长度为L到n所有子序列 double ans=sum[l]; for (i=l+1; i<=n; i++) { dp[i]=maxx[i-l+1]+sum[i]-sum[i-l+1]; if (ans<dp[i]) { ans=dp[i]; } } //修正边界 if (ans>=0) { left = mid; } else { right = mid; } } //输出 printf("%d\n", (int)(right*1000)); return 0; }
- 1
Information
- ID
- 167
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 7
- Tags
- # Submissions
- 42
- Accepted
- 12
- Uploaded By