hdu 1421 搬寝室(dp)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1421
思路:d[i][j] 表示前i 个,k对的最小值。
这个题还是不太好想状态方程,初始化以后,还要分一下情况。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 using namespace std; 7 const int maxn = 2000+10; 8 const int maxm = 1000+10; 9 const int INF = 1<<28; 10 11 int d[maxn][maxm]; 12 int a[maxn]; 13 int _min(int x, int y) 14 { 15 return x>y?y:x; 16 } 17 int main() 18 { 19 int n, k, i, j; 20 while(~scanf("%d%d", &n, &k)) 21 { 22 for(i = 1; i <= n; i++) 23 scanf("%d", &a[i]); 24 sort(a+1, a+n+1); 25 for(i = 0; i < maxn; i++) 26 d[i][0] = 0; 27 28 for(i = 2; i <= n; i++) 29 for(j = 1; j*2 <= i; j++) 30 { 31 if(j*2 <= i-1) 32 d[i][j] = _min(d[i-1][j], d[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1])); //一般情况下,求新增加一个 和以前的比较 33 else 34 d[i][j] = d[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]); //当i为偶数情况时,且j达到最大的时候 35 } 36 printf("%d\n", d[n][k]); 37 } 38 return 0; 39 }