比較有意思的一道題
總的思路就是二分+前綴和,不難,可是其中有的思想仍是有價值的
因此我就主要從這道題入手來淺談二分中的轉化斷定問題spa
咕咕咕,寫不出數學公式來就只貼代碼吧code
double min_ans=0x3f3f3f,max_ans=-0x3f3f3f; for(int i=p; i<=n; ++i) { min_ans=min(min_ans,num[i-p]); max_ans=max(max_ans,num[i]-min_ans); }
二分答案轉化爲斷定問題
這是一個頗有用的思路,藉助二分咱們能夠吧求最優解的問題轉化爲給定一個\(mid\)值
,斷定是否存在一個可行方案評分達到\(mid\)的問題ci
之後會更新的數學
#include<bits/stdc++.h> using namespace std; const double eps=1e-6; const int N=100001; double a[N],num[N],l,r,b[N]; int n,p; double max(double x,double y) { return x>=y?x:y; } double min(double x,double y) { return x<=y?x:y; } int check(double mid) { for(int i=1; i<=n; ++i) num[i]=a[i]-mid,num[i]+=num[i-1]; //處理前綴和 double min_ans=0x3f3f3f,max_ans=-0x3f3f3f; for(int i=p; i<=n; ++i) { min_ans=min(min_ans,num[i-p]); max_ans=max(max_ans,num[i]-min_ans); } if(max_ans<=0) return 0; else return 1; } int main() { cin>>n>>p; for(int i=1; i<=n; ++i) cin>>a[i]; l=0,r=1000000; while(r-l>eps) { double mid=(l+r)/2; if(check(mid)) l=mid; else r=mid; } cout<<int(r*1000); return 0; }