HDU1421 搬寢室 線性dp

2021-09-06 22:08:24 字數 1269 閱讀 3863

題目:

又是一道,沒有思想的題,看了題解,我發現我的dp題幾乎都看了題解,我總是想不好狀態轉移方程,汗顏,以後怎麼比賽啊。

先排序,然後說乙個數學問題。

首先,要怎麼搬呢?即每一對要怎麼取?如果有abcd四個數,且a< (a-c)^2+(b-d)^2

(a-b)^2+(c-d)^2 < (a-d)^2+(b-c)^2

即每對物品都應是重量最為接近的物品,也就是說對n件物品排序後,每對物品都應該是連續的。

定義陣列w[i]為搬第i對物品所消耗的疲勞值;陣列dp[n][k]來表示在n件物品中搬k對的最佳狀態,而達到這一狀態的決策可能為:

第n件物品不搬,即在前n - 1件物品中搬k對,那麼疲勞值仍為dp[n - 1][k];

第n件物品要搬,那麼根據上面所證,第n - 1件物品也要同時搬,即在前n - 2件物品中搬k - 1對物品,再搬最後一對物品,那麼疲勞值為dp[n - 2][k - 1] + w[n - 1]。

為使疲勞值最小,因此最佳策略為取兩種決策中的最小值,即應使:

dp[n][k] = min(dp[n - 1][k], dp[n - 2][k - 1] + w[n - 1])

應該注意的是要考慮邊界問題,dp[i][j]中:

當2 * j > i時,即要搬的數量超過了物品總量,這是不可能發生的,因此此時令dp[i][j]為無窮大;

當j == 0時,即在一對物品都沒搬時,所需疲勞值應該是0,此時令dp[i][j] = 0。

#include #include 

#include

#include

#include

#include

#define inf 0x3f3f3f3ftypedef

long

long

ll;using

namespace

std;

int n,k,w[2010],dp[2010][1010

];int

main()

sort(w+1,w+1+n);

for(int i=1;i)

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

}for(int i=0;i<=n;i++)

dp[i][

0]=0

; //邊界的處理

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

}printf(

"%d\n

",dp[n][k]);

}return0;

}

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 貪心預處理

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

HDU 1421 搬寢室 類似揹包DP

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