动态规划例题

搬寝室

题目描述

搬寝室是很累的,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件物品后的最佳状态是怎样的(也就是最低的疲劳度),请告诉他吧.

输入描述:

每组输入数据有两行,第一行有两个数n,k(2<=2*k<=n<2000).第二行有n个整数分别表示n件物品的重量(重量是一个小于2^15的正整数).

输出描述:

对应每组输入数据,输出数据只有一个表示他的最少的疲劳度,每个一行.
示例1

输入

2 1
1 3

输出

4

解题思路:这道题可以先依据物品的重量对物品进行排序,
然后从低到高每次选择相邻两个组成一对
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<limits.h>
 5 
 6 int cmp( const void *a,const void *b)
 7 {
 8     return *( int *)a- *(int *)b;  //递增排序
 9 }
10 int goods[2002]; //保存每个物品的重量
11 int dp[1001][2001];  //在前j件物品中选择i对物品时的最小疲劳度
12 int main()
13 {
14     int n,k;
15     int i,j;
16     while( scanf("%d%d",&n,&k)!=EOF)
17     {
18         for( i=1; i<=n; i++)
19             scanf("%d",&goods[i]);
20         qsort( goods+1, n,sizeof(goods[0]),cmp);
21         for( i=1; i<=n; i++)
22             dp[0][i] = 0;  //不选择任何一对物品时,疲劳度为0
23         for( i=1; i<=k; i++)
24         {
25             for( j=2*i; j<=n; j++)
26             {
27                 if( j>2*i)
28                     dp[i][j] = dp[i][j-1]; //若j>2*i则表明最后两个物品可以不配对
29                 else dp[i][j] = INT_MAX;
30                 if( dp[i][j] > dp[i-1][j-2]+(goods[j]-goods[j-1])*(goods[j]-goods[j-1]))
31                     //即前 j-2件物品配成i-1对再加上最后两件配成的一对物品,共得到i对物品
32                     dp[i][j] = dp[i-1][j-2]+(goods[j]-goods[j-1])*(goods[j]-goods[j-1]);
33             }
34         }
35         printf("%d
",dp[k][n]);
36     }
37 
38     return 0;
39 }

在这里我还加入了 <limits.h> 用于简便最大值的选取


 1 #include <stdio.h>
 2 #include <limits.h>
 3 
 4 int main()
 5 {
 6 
 7    printf("The number of bits in a byte %d
", CHAR_BIT);
 8 
 9    printf("The minimum value of SIGNED CHAR = %d
", SCHAR_MIN);
10    printf("The maximum value of SIGNED CHAR = %d
", SCHAR_MAX);
11    printf("The maximum value of UNSIGNED CHAR = %d
", UCHAR_MAX);
12 
13    printf("The minimum value of SHORT INT = %d
", SHRT_MIN);
14    printf("The maximum value of SHORT INT = %d
", SHRT_MAX); 
15 
16    printf("The minimum value of INT = %d
", INT_MIN);
17    printf("The maximum value of INT = %d
", INT_MAX);
18 
19    printf("The minimum value of CHAR = %d
", CHAR_MIN);
20    printf("The maximum value of CHAR = %d
", CHAR_MAX);
21 
22    printf("The minimum value of LONG = %ld
", LONG_MIN);
23    printf("The maximum value of LONG = %ld
", LONG_MAX);
24   
25    return 0;
26 }


在这个国度中,必须不停地奔跑,才能使你保持在原地。如果想要寻求突破,就要以两倍现在速度奔跑!
原文地址:https://www.cnblogs.com/yuxiaoba/p/8456801.html