HDOJ1421 搬寢室 動態規劃 貪心

2021-08-29 07:08:18 字數 1623 閱讀 6833

題目鏈結 

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

題解: 從n件物品中選k對,要求每對差平方之和最小。

先把n件物品從小到大按重量sort一遍,假設最終選擇的某對物品中間空了至少1件物品沒選,那把這對物品任何一件換成中間空的物品來選,這樣得到的結果必定更小,所以這種情況下這對物品得相鄰。

假設如果是至少2對物品相互交錯的情況,

比如有4件物品重量為 1,2,3,4

最終選擇2對物品分別為(1,3),(2,4)

將選擇的3與2對調,即改為(1,2),(3,4),

這樣結果更小,

所以用這種貪心的思想可以得出結論,最終結果每對物品肯定相鄰。這樣這題就好做了。

然後dp思想,dp[j]表示只有前j件物品可選擇,如果第j件物品不選,那dp[j] = dp[j-1],(假設選擇i對物品)

否則,那第j和j-1這對物品必選,dp[j] = dp[j-2] + (a[j]-a[j-1])^2;

以上2個值取最小就ok。

但其實第二個轉移方程是錯的,因為已經選了最後那對物品,dp[j-2]表示從前j-2件物品中選i對,這樣就有i+1對了,當前只求選擇i對的情況。

所以需要用另乙個陣列把上一次選擇i-1對物品的結果記錄下來。

另外需要注意的是,如果2*i==j,即必須選的物品數就是總物品數,那dp就直接取第二個方程即可。

#include #include #include #include #include #define inf 2000000000

using namespace std;

int n,k;

int dp[2005];

int a[2005];

int t[2005];// 用於儲存上一次dp迴圈的結果

int main()

dp[j] = min(dp[j-1],t[j-2] + (a[j]-a[j-1]) * (a[j]-a[j-1]));

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

}return 0;

}

hdoj1421 搬寢室 dp基礎題)

目錄 搬寢室解題思路 ac problem description 搬寢室是很累的,xhd深有體會.時間追述2006年7月9號,那天xhd迫於無奈要從27號樓搬到3號樓,因為10號要封樓了.看著寢室裡的n件物品,xhd開始發呆,因為n是乙個小於2000的整數,實在是太多了,於是xhd決定隨便搬2 k...

動態規劃 hdu 1421 搬寢室

problem description 搬寢室是很累的,xhd深有體會.時間追述2006年7月9號,那天xhd迫於無奈要從27號樓搬到3號樓,因為10號要封樓了.看著寢室裡的n件物品,xhd開始發呆,因為n是乙個小於2000的整數,實在是太多了,於是xhd決定隨便搬2 k件過去就行了.但還是會很累,...

HDU1421 搬寢室 動態規劃

動態規劃題 題意是輸入兩個整數n和k,表示從n件物品中搬走k對 每次左右手各搬一件 已知每件物品的疲勞值,求搬走k對後的最小疲勞度。每個物品的疲勞度用ans存起來,很明顯,把ans按公升序排序後每相鄰兩個物品的疲勞度都是最小的 然後定義陣列dp i j 表示從前i件物品中搬走j對的總疲勞度,則對於第...