1. 程式人生 > >題解報告:hdu 1421 搬寢室

題解報告:hdu 1421 搬寢室

con main class 質量 urn 一道 http hdu HP

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1421

解題思路:這是一道典型的dp問題。狀態轉移思想:將物品按質量遞增排序後,從前i件物品中拿走j對(j*2<=i)時,
(1)不拿第i件,則dp[i][j]=dp[i-1][j],這個毫無疑問。
(2)拿第i件物品,則第i件物品肯定和第i-1件物品一起拿,則dp[i][j]=dp[i-2][j-1]+(a[i]-a[i-1])^2,即從前i-2件中拿j-1對的疲勞值加上拿了最後兩件物品的疲勞值(當然,由前到後處理的,i和j前面的所有情況都已經處理好了,都是最小值)。狀態轉移方程:dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i-1]-a[i-2])*(a[i-1]-a[i-2]))。

註:此處用a[i-1]-a[i-2]是因為a是從下標0開始的。
AC代碼:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a[2005],dp[2005][1005];
 4 const int INF=0x3f3f3f3f;
 5 int main()
 6 {
 7     int n,k;
 8     while(cin>>n>>k){
 9         memset(dp,INF,sizeof(dp));//初始化為最大值,以便比較取最小值
10         for(int i=0;i<n;i++){
11 cin>>a[i]; 12 dp[i][0]=0;//同時將前i件物品中取走j=0對賦初值為0,不需要選任何物品 13 } 14 sort(a,a+n);//排序 15 for(int i=2;i<=n;i++){//i從2開始,枚舉到(包括)n,題目有要求 16 for(int j=1;j*2<=i&&j<=k;j++)//j是枚舉到k 17 dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i-1
]-a[i-2])*(a[i-1]-a[i-2]));//從0開始 18 } 19 cout<<dp[n][k]<<endl; 20 } 21 return 0; 22 }

題解報告:hdu 1421 搬寢室