HDU 1421 搬寢室 線性dp 貪心預處理

2021-07-03 20:23:13 字數 1286 閱讀 9189

problem description

搬寢室是很累的,xhd深有體會.時間追述2023年7月9號,那天xhd迫於無奈要從27號樓搬到3號樓,因為10號要封樓了.看著寢室裡的n件物品,xhd開始發呆,因為n是乙個小於2000的整數,實在是太多了,於是xhd決定隨便搬2*k件過去就行了.但還是會很累,因為2*k也不小是乙個不大於n的整數.幸運的是xhd根據多年的搬東西的經驗發現每搬一次的疲勞度是和左右手的物品的重量差的平方成正比(這裡補充一句,xhd每次搬兩件東西,左手一件右手一件).例如xhd左手拿重量為3的物品,右手拿重量為6的物品,則他搬完這次的疲勞度為(6-3)^2 = 9.現在可憐的xhd希望知道搬完這2*k件物品後的最佳狀態是怎樣的(也就是最低的疲勞度),請告訴他吧.

input

每組輸入資料有兩行,第一行有兩個數n,k(2<=2*k<=n<2000).第二行有n個整數分別表示n件物品的重量(重量是乙個小於2^15的正整數).

output

對應每組輸入資料,輸出資料只有乙個表示他的最少的疲勞度,每個一行.

sample input

2 1

1 3

sample output

4

題目大意:久違的中文題,不解釋

題目分析:顯然左右手物品重量越接近越好,先按照重量從小到大排序,然後預處理出相鄰兩個數的差值的平方b[i] = (a[i + 1] - a[i])^2,這樣預處理也直接把2k化成k了,顯然b[i]和b[i + 1]是不能同時取的,定義dp[i][j]為b陣列的前i個取了j個時的最少疲勞度,轉移方程dp[i][j] = min(dp[i - 1][j], dp[i - 2][j - 1] + b[i]),初始化dp[i][0]=0,dp[1][1]=b[1],其他inf

#include #include #include using namespace std;

int const max = 2005;

int const inf = 0x3fffffff;

int dp[max][max], a[max], b[max];

int main()

dp[1][1] = b[1];

for(int i = 2; i <= n; i++)

for(int j = 1; j <= k; j++)

dp[i][j] = min(dp[i - 1][j], dp[i - 2][j - 1] + b[i]);

printf("%d\n", dp[n][k]);

}}

HDU1421 搬寢室 線性dp

題目 又是一道,沒有思想的題,看了題解,我發現我的dp題幾乎都看了題解,我總是想不好狀態轉移方程,汗顏,以後怎麼比賽啊。先排序,然後說乙個數學問題。首先,要怎麼搬呢?即每一對要怎麼取?如果有abcd四個數,且a a c 2 b d 2 a b 2 c d 2 a d 2 b c 2 即每對物品都應是...

hdu 1421 搬寢室 dp問題

以前雖然寫過dp問題,但思想上過不去,覺得dp跟遞迴似乎是一樣的,今天寫過這道題後才頓悟 dp與遞迴不是一樣的。狀態方程dp n k min dp n 1 k dp n 2 k 1 w i w j 2 唉,終於發現思想上有所改變了,不過 實現能力不足,在對dp陣列初始化的問題上浪費了n多精力和時間 ...

HDU 1421 搬寢室 類似揹包DP

思路 把重物從小到大排序,計算出每2個相鄰的重物產生的疲勞度,放在p i 陣列中,表示i與i 1這2個重物產生的疲勞度。dp i j 表示進行到第i個物品 i前面的物品不一定都選了,跟揹包差不多,i表示進行到第i個物品 已經選了j對物品 產生的最小疲勞度。初始化 先把所有值賦值為inf 無窮大 然後...