日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Loj#2035-[SDOI2016]征途【斜率优化】

發布時間:2023/12/3 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Loj#2035-[SDOI2016]征途【斜率优化】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://loj.ac/problem/2035


題目大意

nnn個數字分成mmm段,要求方差最小。


解題思路

首先方差的公式∑i=1n(xi?∣x∣)2\sum_{i=1}^n(x_i-|x|)^2i=1n?(xi??x)2
其中∣x∣|x|x是不變的,定義w=∣x∣w=|x|w=x
fi,jf_{i,j}fi,j?表示已經分到第iii段,到第jjj個時的最小方差和。

做前綴和si=∑j=1iais_i=\sum_{j=1}^ia_isi?=j=1i?ai?
之后有fk,i=min{fk?1,j+(si?sj)2+w2?2(si?sj)w}f_{k,i}=min\{f_{k-1,j}+(s_i-s_j)^2+w^2-2(s_i-s_j)w\}fk,i?=min{fk?1,j?+(si??sj?)2+w2?2(si??sj?)w}
去掉minminmin拆括號
fk,i=fk?1,j+si2?2sisj+sj2+w2?2siw+sjwf_{k,i}=f_{k-1,j}+s_i^2-2s_is_j+s_j^2+w^2-2s_iw+s_jwfk,i?=fk?1,j?+si2??2si?sj?+sj2?+w2?2si?w+sj?w
fk,i?si2+siw+2sisj?2sjw=fk?1,j+sj2f_{k,i}-s_i^2+s_iw+2s_is_j-2s_jw=f_{k-1,j}+s_j^2fk,i??si2?+si?w+2si?sj??2sj?w=fk?1,j?+sj2?
fk,if_{k,i}fk,i?最小就是fk,i?si2+siwf_{k,i}-s_i^2+s_iwfk,i??si2?+si?w最小,后為了方便
定義F=fk,i?si2+siwF=f_{k,i}-s_i^2+s_iwF=fk,i??si2?+si?w
F+2(si?w)sj=fk?1,j+sj2F+2(s_i-w)s_j=f_{k-1,j}+s_j^2F+2(si??w)sj?=fk?1,j?+sj2?
然后有若干個決策點(sj,fk?1,j+sj2)(s_j,f_{k-1,j}+s_j^2)(sj?,fk?1,j?+sj2?)
每次有一條直線y=2(si?w)x+Fy=2(s_i-w)x+Fy=2(si??w)x+F經過某個決策點要求FFF最小
顯然因為si?ws_i-wsi??w的單調性和sjs_jsj?的單調性我們可以使用單調隊列維護一個下凸殼。

時間復雜度O(nm)O(nm)O(nm)


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> #define pow2(x) ((x)*(x)) using namespace std; const int N=3100; struct node{double x,y;int num; }q[N]; int n,m; double s[N],f[N][N]; double slope(node x,node y) {return (y.y-x.y)/(y.x-x.x);} int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%lf",&s[i]),s[i]=s[i]*m+s[i-1];double w=s[n]/m;for(int i=1;i<=n;i++)f[1][i]=pow2(s[i]-w);for(int k=2;k<=m;k++){int head=1,tail=1;q[1]=(node){s[k-1],f[k-1][k-1]+pow2(s[k-1]),k-1};for(int i=k;i<=n;i++){int z=2*(s[i]-w);while(head<tail&&slope(q[head],q[head+1])<z)head++;int p=q[head].num;f[k][i]=f[k-1][p]+pow2(s[i]-s[p]-w);node po=(node){s[i],f[k-1][i]+pow2(s[i]),i};while(head<tail&&slope(po,q[tail])<slope(q[tail-1],q[tail]))tail--;q[++tail]=po;}}printf("%.0lf",f[m][n]/m); }

總結

以上是生活随笔為你收集整理的Loj#2035-[SDOI2016]征途【斜率优化】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。