題解報告:hdu 1421 搬寢室
阿新 • • 發佈:2018-03-08
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 搬寢室