• HDU-3480 Division 【DP+斜率优化(二维)】


    题目链接

    题意

    定义一个集合的花费是这个集合中的最大值减最小值的平方。然后给定一个集合S,求对这个集合的一个覆盖,使得所有子集的花费和最小。

    分析

    本身这个题是非常简单的,只是今天看了别人的题解,我发现我以前写的二维斜率优化都写复杂了。直接外层循环用未被优化的那一维就行了,不用像我以前那样维护一个k维的单调队列……我说怎么不对劲,每次看别人的代码都那么短……
    具体见代码

    AC代码

    //HDU-3480 Division
    //AC  2017-3-11 14:52:18
    //DP, slope trick(2d)
    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e4+100,maxm=5e3+100;
    
    int N,M;
    int dp[maxn][2],a[maxn];
    int que[maxn];
    int head,tail;
    
    int getx(int j)
    {
        return a[j+1];
    }
    
    int gety(int j,int flag)
    {
        return dp[j][!flag]+a[j+1]*a[j+1];
    }
    
    void insert(int i,int flag)
    {
        while(tail>head+1&&
              (gety(i,flag)-gety(que[tail-1],flag))*(getx(que[tail-1])-getx(que[tail-2]))<=
              (gety(que[tail-1],flag)-gety(que[tail-2],flag))*(getx(i)-getx(que[tail-1])))
                tail--;
        que[tail++]=i;
        return;
    }
    
    int get_front(int i,int flag)
    {
        while(tail>head+1&&
              (gety(que[head+1],flag)-gety(que[head],flag))<=(getx(que[head+1])-getx(que[head]))*2*a[i])
                ++head;
        return gety(que[head],flag)-2*a[i]*getx(que[head]);
    }
    
    
    int main()
    {
        int T;scanf("%d",&T);
        for(int kase=1;kase<=T;++kase)
        {
            scanf("%d %d",&N,&M);
            if(N<=M)
            {
                printf("Case %d: 0
    ",kase);
                continue;
            }
            for(int i=1;i<=N;++i)
                scanf("%d",a+i);
            sort(a+1,a+1+N);
            memset(dp,0x3f,sizeof dp);
            int flag=0;
            for(int i=1;i<=N;++i)
                dp[i][flag]=(a[i]-a[1])*(a[i]-a[1]);
            flag=!flag;
            for(int k=2;k<=M;++k)
            {
                head=tail=0;
                dp[1][flag]=dp[1][!flag];
                insert(1,flag);
                for(int i=2;i<=N;++i)
                {
                    dp[i][flag]=get_front(i,flag)+a[i]*a[i];
                    insert(i,flag);
                }
                flag=!flag;
            }
            /*for(int i=1;i<=N;++i)
            {
                dp[i][1]=(a[i]-a[1])*(a[i]-a[1]);
                insert(i,1);
                for(int k=2;k<=min(M,i);++k)
                {
                    dp[i][k]=get_front(i,k-1)+a[i]*a[i];
                    insert(i,k);
                }
            }*/
            printf("Case %d: %d
    ",kase,dp[N][!flag]);
        }
        return 0;
    }
  • 相关阅读:
    linux下配置SS5(SOCK5)代理服务
    HttpServletRequest修改/添加header和cookie参数
    jquery ajax 设置全局(常量和变量)
    mysql 5.1超过默认8小时空闲时间解决办法(错误:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure)
    jquery带token访问接口ajax
    CentOS 7下彻底卸载MySQL数据库
    IntelliJ IDEA 终极破解
    haproxy+tomcat实现负载均衡以及session共享(linux centos7环境)
    RocketMQ集群搭建
    IntelliJ IDEA14如何配置tomcat
  • 原文地址:https://www.cnblogs.com/DrCarlluo/p/6580569.html
Copyright © 2020-2023  润新知