hdu1421

来源:互联网 发布:cms管理系统模板 编辑:程序博客网 时间:2024/05/16 08:43

状态方程为:

dp[i][j]表示前i个物品选j对的最小消耗

则如果不选第i个物品,dp[i][j]=dp[i-1][j]

否则,dp[i][j]=dp[i-2][j-1]+后两个物品的消耗

两者取最小即可:dp[i][j] = min(dp[i-1][j], dp[i-2][j-1]+pf(wp[i] - wp[i-1]));


#include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <iterator>
#include <cstring>
#include <cmath>


#define pf(a) ((a)*(a))


using namespace std;




//  dp[i][j]:前i个物品中挑出j对的最小消耗
long long dp[2005][1005];


long long wp[2005];


int main() {
    int n, k;


    while (cin >> n >> k) {
        memset(dp, 0, sizeof(dp));
        for (int i = 1; i <= n; i++) cin >> wp[i];
        sort(wp+1, wp+n+1);
        dp[2][1] = pf(wp[1] - wp[2]);
        for (int i = 3; i <= n; i++) {
            for (int j = 1; j<=i/2 && j <= k; j++) {
                if (2*j==i) {
                    long long sum = 0;
                    for (int k = 1; k <= i; k+=2) {
                        sum += pf(wp[k]-wp[k+1]);
                    }
                    dp[i][j] = sum;
                } else {
                    dp[i][j] = min(dp[i-1][j], dp[i-2][j-1]+pf(wp[i] - wp[i-1]));
                }
            }
        }
        cout << dp[n][k] << endl;
    }




    return 0;


}

0 0
原创粉丝点击