hdu 3480 Division (四边形不等式优化DP)

题目描述

传送门

题目大意:将n个数划分到m个集合中,每个集合的代价是集合中最大元素与最小元素差的平方。求划分的最小代价。

题解

这个问题可以贪心的想,必然是权值接近的分成一个集合。
那么我们只要把权值排序,问题就又变成了划分问题。
f[j][i]=min{f[k][i1]+(val[j]val[k+1])(val[j]val[k+1])}
然后一如既往的用四边形不等式优化。。。。

代码

#include
#include
#include
#include
#define LL long long 
#define inf 1000000000
using namespace std;
int val[10003],dp[10003][5003],s[10003][5003];
int n,m,T;
int pow(int x)
{
    return x*x;
}
int main()
{
    freopen("a.in","r",stdin);
    scanf("%d",&T);
    for (int t=1;t<=T;t++) {
       scanf("%d%d",&n,&m);
       for (int i=1;i<=n;i++) scanf("%d",&val[i]);
       sort(val+1,val+n+1);
       //for (int i=1;i<=n;i++) cout<
       //cout<
       memset(dp,0,sizeof(dp));
       for (int i=1;i<=n;i++) 
        dp[i][1]=pow(val[i]-val[1]),s[i][1]=0;
       for (int i=2;i<=m;i++) {
          s[n+1][i]=n;
          for (int j=n;j>i;j--) {
            dp[j][i]=inf;    
            for (int k=s[j][i-1];k<=s[j+1][i];k++) {
               int tmp=dp[k][i-1]+pow(val[j]-val[k+1]);
               if (tmpprintf("Case %d: %d\n",t,dp[n][m]);
    }
}

你可能感兴趣的:(动态规划)