程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdu 1421 搬寢室

hdu 1421 搬寢室

編輯:C++入門知識

hdu 1421 搬寢室


 

搬寢室

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 19201 Accepted Submission(s): 6530



Problem Description 搬寢室是很累的,xhd深有體會.時間追述2006年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

 

思路:顯然,可以把物品按重量從小到大排序,每次選某個物品時肯定和它相鄰的組成一組。

對於當前物品i,考慮選或者不選。

若是不選,可以從i-1件物品選k對;否則,選定該物品,則i-1物品必選,則從i-2中選k-1件物品。

狀態轉移方程為:dp[i][j]=min(dp[i-1][k],dp[i-2][k-1]+(a[i]-a[i-1])^2);

dp太弱,好長時間不寫代碼,好多bug!

 

 

#include
#include
#include
#include
#include
#include
using namespace std;
#define N 2100
#define ll __int64
const int inf=0x7fffffff;
int a[N];
ll dp[N][N/2];
int n,k;
void inti()
{
    int i,j;
    for(i=0;i<=n;i++)
        for(j=0;j<=k;j++)
        dp[i][j]=inf;
}
ll comp(int i,int j)
{
    ll t=a[i]-a[j];
    return t*t;
}
int main()
{
    int i,j;
    while(~scanf("%d%d",&n,&k))
    {
        inti();
        dp[0][0]=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            dp[i][0]=0;
        }
        sort(a+1,a+n+1);
        for(i=1;i<=k;i++)
        {
            for(j=i*2;j<=n;j++)
            {
                dp[j][i]=min(dp[j-1][i],dp[j-2][i-1]+comp(j,j-1));
            }
        }
        printf("%I64d\n",dp[n][k]);
    }
    return 0;
}


 

 

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved