zoukankan      html  css  js  c++  java
  • HDU 3480

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3480

    Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 999999/400000 K (Java/Others)

    Little D is really interested in the theorem of sets recently. There’s a problem that confused him a long time.   
    Let T be a set of integers. Let the MIN be the minimum integer in T and MAX be the maximum, then the cost of set T if defined as (MAX – MIN)^2. Now given an integer set S, we want to find out M subsets S1, S2, …, SM of S, such that 
    and the total cost of each subset is minimal.

    Input

    The input contains multiple test cases. 
    In the first line of the input there’s an integer T which is the number of test cases. Then the description of T test cases will be given. 
    For any test case, the first line contains two integers N (≤ 10,000) and M (≤ 5,000). N is the number of elements in S (may be duplicated). M is the number of subsets that we want to get. In the next line, there will be N integers giving set S. 

    Output

    For each test case, output one line containing exactly one integer, the minimal total cost. Take a look at the sample output for format. 

    Sample Input

    2
    3 2
    1 2 4
    4 2
    4 7 10 1

    Sample Output

    Case 1: 1
    Case 2: 18

    题意:

    给出含有N元素的集合S,选取M个S的子集,要求满足SU S2 U … U SM = S;

    定义一个集合的最大元素为MAX,最小元素为MIN,它的花费为(MAX - MIN)2,现要求所有子集的总花费最少为多少。

    题解:

    先将S内元素从小到大排列,然后将这N个元素的序列分成M组(因为若有重叠元素,必然会使得花费增加);

    那么假设dp[i][j]为前i个数分成j组的最小花费,那么求出dp[N][M]即可回答问题;

    状态转移方程为dp[i][j] = min{ dp[k][j-1] + (S[i] - S[k+1])2 },j-1≤k<i;

    那么当j固定时,计算dp[i][j]时需要枚举k,若k可能取值到a,b两点,且j-1≤a<b<i,

    若有 dp[b][j-1] + (S[i] - S[b+1])2 ≤ dp[a][j-1] + (S[i] - S[a+1])2,则b点优于a点;

    将上式变形,得到:

    b点优于a点 <=> 

    再然后就是斜率优化的老套路了(斜率优化的详情查看斜率DP分类里之前的文章),就不再赘述。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=10000+5;
    
    int n,m,S[maxn];
    int dp[maxn][maxn];
    int q[maxn],head,tail;
    
    int up(int a,int b,int j) //g(a,b)的分子部分
    {
        return (dp[b][j-1]+S[b+1]*S[b+1])-(dp[a][j-1]+S[a+1]*S[a+1]);
    }
    int down(int a,int b) //g(a,b)的分母部分
    {
        return 2*S[b+1]-2*S[a+1];
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        for(int kase=1;kase<=t;kase++)
        {
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++) scanf("%d",&S[i]);
            sort(S+1,S+n+1);
    
            for(int i=1;i<=n;i++) dp[i][1]=(S[i]-S[1])*(S[i]-S[1]);
            for(int j=2;j<=m;j++)
            {
                head=tail=0;
                q[tail++]=j-1;
                for(int i=j;i<=n;i++)
                {
                    while(head+1<tail)
                    {
                        int a=q[head], b=q[head+1];
                        if(up(a,b,j)<=S[i]*down(a,b)) head++; //g(a,b)<=S[i]
                        else break;
                    }
                    int k=q[head];
                    dp[i][j]=dp[k][j-1]+(S[i]-S[k+1])*(S[i]-S[k+1]);
    
                    while(head+1<tail)
                    {
                        int a=q[tail-2], b=q[tail-1];
                        if(up(a,b,j)*down(b,i)>=up(b,i,j)*down(a,b)) tail--; //g(a,b)>=g(b,i)
                        else break;
                    }
                    q[tail++]=i;
                }
            }
    
            printf("Case %d: %d
    ",kase,dp[n][m]);
        }
    }

    注意DP边界的初始化。

  • 相关阅读:
    MVC模式简介
    UEditor插入表格没有边框但有间距
    MVC准备前基础知识
    如何关闭ie9烦人的提示信息?
    javaScript中利用ActiveXObject来创建FileSystemObject操作文件
    win7下IIS安装与配置运行网站
    javascript函数
    减小SSN影响
    EMC (电磁兼容性)
    电源完整性设计
  • 原文地址:https://www.cnblogs.com/dilthey/p/8878094.html
Copyright © 2011-2022 走看看