hdu 1421 搬寝室

来源:互联网 发布:mp3播放器推荐 知乎 编辑:程序博客网 时间:2024/04/28 01:28

DP。

这题初看就感觉变换下应该比较好做,先排序,然后可以相邻两个数相减,然后求K个不相邻的数的最小和。

后来觉得这个思路不会找K个不相邻数最小和 T T。。

后来PPT上也有讲,找I个物品选K对。

吃饭回来想了下,也不算麻烦。想清楚后开始搞 = =。。发现。。初始化真恶心。

状态转移方程是

dp[k][i] = min(dp[k-1][i-2]+ (a[i]-a[i-1])*(a[i]-a[i-1]), dp[k][i-1]);

表示前 i 个物品,取k对的最小和。


#include <queue>#include <stack>#include <math.h>#include <time.h>#include <stdio.h>#include <stdlib.h>#include <iostream>#include <limits.h>#include <string.h>#include <string>#include <algorithm>#define MID(x,y) ( ( x + y ) >> 1 )#define L(x) ( x << 1 )#define R(x) ( x << 1 | 1 )#define BUG puts("here!!!")using namespace std;const int MAX = 2010;int dp[MAX][MAX];int a[MAX];int main(){    int n, K;        while( ~scanf("%d%d",&n,&K) )    {        for(int i=1; i<=n; i++)                scanf("%d",&a[i]);                sort(a+1, a+n+1);                int t = 0;        memset(dp,0,sizeof(dp));        for(int i=1; i<=K; i++)            for(int k=i*2; k<=n; k++)                dp[i][k] = INT_MAX;                        for(int i=1; i<=2*K; i+=2)        {            t += (a[i+1] - a[i])*(a[i+1] - a[i]);            dp[i/2+1][(i/2+1)*2] = t;        }                for(int k=1; k<=K; k++)            for(int i=2*k+1; i<=n; i++)                dp[k][i] = min(dp[k-1][i-2]+ (a[i]-a[i-1])*(a[i]-a[i-1]), dp[k][i-1]);        printf("%d\n",dp[K][n]);    }return 0;}


原创粉丝点击