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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

UESTC_摩天轮 2015 UESTC Training for Dynamic ProgrammingProblem K

發布時間:2025/7/14 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UESTC_摩天轮 2015 UESTC Training for Dynamic ProgrammingProblem K 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

K - 摩天輪

Time Limit: 10000/4000MS (Java/Others) ??? Memory Limit: 262143/262143KB (Java/Others)
Submit?Status

一天,冬馬被春希和雪菜拉著去一起去游樂園玩。

經過了各種過山車的洗禮后,三人決定去坐摩天輪休息下。

這是一個巨大的摩天輪,每一個車廂能坐任意多的人。現在,等著坐摩天輪的有n個人(包含他們3人),摩天輪還有m個車廂可以坐人。每個人都有自己肥胖程度,出于某些原因,胖子和瘦子坐在同一節車廂就會產生一定的矛盾,這個矛盾的值為(MAX?MIN)2,其中MAX為當前車廂里面最胖的人的肥胖程度,MIN為最廋的那個人的肥胖程度。

愛管閑事的春希當然不希望就因為這點小事而使大家的這趟旅途不愉快,于是他決定幫大家安排怎么坐才能使總的矛盾值最小,希望你能幫他找到這個最小的矛盾值

Input

第一行為兩個整數nm,分別表示人數和車廂數。(3n10000,1m5000)

第二行為n個整數,wi表示第i個人的肥胖程度。(0wi1000000)

Output

每組數據,輸出一個整數,為矛盾的最小值。(答案保證小于231

Sample input and output

Sample InputSample Output
4 2 4 7 10 1 18

?

解題思路:

這是一道斜率優化DP的題目.

?我們令 f ( i , j ) 表示將前 i 個人分成 j 份所需的最小費用.

F ( i , j ) = min{ F ( u , j -1) + (sum[i] – sum[ u + 1])^2 }

但是這樣做的復雜度高達O(N^2*M),對于本題的規模來講無法承受,我們考慮

K1 < k2 < i ,且 k2 比 k1更優

有式子

?F ( k2 , j - 1 ) + sum( k2 ) ^ 2 -? F( k1 , j -1 ) – sum(k1+1) ^ 2

?—————————————————————?—————————————?? < 2 * sum(i)

???????????? sum ( k2 ) – sum( k1+1)

顯然這是一個斜率的式子.

假設現在 K(k1 – k2) < 2*sum[i] ,那么k1這個點還有價值嗎?

我們注意到sum[i]是單調不減的,也就是說,對于之后的i2,i3…..

K(k1 – k2) < 2*sum[i_x] ,也就是說,k1 完全不可能成為某個點的最優解了,是可以舍棄的.

那么如果現在有 K(k1 – k2) >= 2*sum[i]呢,目前顯然是選擇k1比k2好,我們應不應該舍棄k2呢?答案是不應該,因為隨著i的增大,sum[i]是不減的(也就是說,sum[i]可能會增大),此時 K(k1 – k2) < 2*sum[i] 是可能成立的.

綜上所述,我們維護一個單調隊列即可,只不過這個單調隊列剔除 / 加入元素的條件都是和與斜率有關,這樣我們可以在O(1)的時間內得到某個點的最優決策點,復雜度成功降到了O(n*m).

?

代碼使用了滾動數組進行優化

#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int maxn = 1e4 + 50; int n,m,h[maxn],f[2][maxn],cur=0,q[maxn];double slope(int x,int y) {if (h[x+1] == h[y+1])return 1e233;return (double)(f[cur^1][x] + h[x+1]*h[x+1] - (f[cur^1][y] + h[y+1]*h[y+1])) / (double)(h[x+1] - h[y+1]); }int main(int argc,char *argv[]) {scanf("%d%d",&n,&m);for(int i = 1 ; i <= n ; ++ i) scanf("%d",&h[i]);sort(h+1,h+1+n);for(int i = 1; i <= n ; ++ i) f[cur][i] = (h[i]-h[1])*(h[i]-h[1]);for(int i = 2 ; i <= m ; ++ i){cur ^= 1;int front = 0 , rear = 0 ;q[rear++] = 1;for(int j = 2 ; j <= n ; ++ j){while (rear - front > 1 && slope(q[front],q[front+1]) <= 2*h[j])front++;f[cur][j] = f[cur^1][q[front]] + (h[j] - h[q[front]+1])*(h[j] - h[q[front]+1]);while(rear - front > 1 && slope(q[rear-2],q[rear-1]) >= slope(q[rear-1],j))rear--;q[rear++] = j;}}printf("%d\n",f[cur][n]);return 0; }

?

轉載于:https://www.cnblogs.com/Xiper/p/4539638.html

總結

以上是生活随笔為你收集整理的UESTC_摩天轮 2015 UESTC Training for Dynamic ProgrammingProblem K的全部內容,希望文章能夠幫你解決所遇到的問題。

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