1. 程式人生 > >hdu 1421 搬寢室(dp)

hdu 1421 搬寢室(dp)

ios 7月 out itl 兩件 int names panel 思路

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 思路:首先,我們應該對輸入數據進行一次排序,按順序排好後很容易可以知道相鄰兩個的物品重量差一定是對於這兩個物品來說是最小的。 DP[ i ][ j ] = min(DP[ i-1 ][ j ],DP[ i - 2][ j - 1] + (a[ i ] - a [ i - 1 ])^2)
#include <cstdio>
#include <map>
#include <iostream>
#include<cstring>
#include<bits/stdc++.h>
#define ll long long int
#define M 6
using namespace std;
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
int moth[13
]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1}; int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1}; const int inf=0x3f3f3f3f; const ll mod=1e9+7; int n,k; int a[2007]; int dp[2007][2007]; //表示前i個物品中選擇了j對 int main(){ ios::sync_with_stdio(false); while(cin>>n>>k){ for(int i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+1+n); //保證相差最小 for(int i=1;i<=n;i++) for(int j=1;j<=k;j++) dp[i][j]=inf; dp[0][0]=0; for(int i=2;i<=n;i++) for(int j=1;2*j<=i;j++){ dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1])); } cout<<dp[n][k]<<endl; } return 0; }

hdu 1421 搬寢室(dp)