要说我校的搬家史那可有的说的了。就alpha来说,他这个暑假刚经历一次搬寝室。
alpha寝室里的东西有n件,但搬东西真的是件很累的事,他只准备随便搬2*m件就行。
alpha每趟左手、右手分别拎一件物品。
凭借天资聪颖,他迅速地发现了:每搬一趟,他的疲劳度与左、右手的物品的重量差的平方成正比。例如他左手拿重量为3的物品,右手拿重量为6的物品,则他搬完这次的疲劳度为(6-3)^2 = 9.
他想知道他搬完这2*m件物品后疲劳度最低是多少?
每组输入数据有两行。
第一行有两个数n,m (2*m ≤ n < 2000)。
第二行有n个整数分别表示n件物品的重量(重量是一个小于215的正整数)。
0 0表示输入结束。
对于每组输入数据,输出一个正整数,表示他最少的疲劳度,每组输出占一行。
5 1
18467 6334 26500 19169 15724
7 1
29358 26962 24464 5705 28145 23281 16827
0 0
492804 1399489
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream>
2 #include<cstring>
3 //#include<fstream>
4 #include<algorithm>
5 int a[2050],dp[2050][2050];
6 using namespace std;
7 #define inf 0x3f3f3f3f
8 int main(){
9 int n,k;
10 //fstream file("haha.txt");
11 while(cin>>n>>k&&n){
12 for(int i=1;i<=n;i++){
13 cin>>a[i];
14 }
15 sort(a+1,a+n+1);
16 memset(dp,0,sizeof(dp));
17 for(int i=1;i<=n;i++){
18 for(int j=1;j<=k;j++){
19 dp[i][j]=inf;
20 }
21 }
22 for(int i=2;i<=n;i++){
23 for(int j=1;j*2<=i;j++){
24 dp[i][j]=min(dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]),dp[i-1][j]);
25 }
26 }
27 cout<<dp[n][k]<<endl;
28 }
29 return 0;
30 }
贪心加动态规划,贪心的思想体现在要将他们排序,排序后,相邻的数的差平方一定比不相邻的小,
然后是动态规划的思想,dp[i][j]表示,从i个物品中拿j对物品的最小值
拿第i个物品的情况是,dp[i][j]=dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]),
不拿第i个物品的情况是,dp[i][j]=dp[i-1][j]