zoukankan      html  css  js  c++  java
  • 迎春舞会之三人组舞 vijos1061 动态规划

    描述

    n个人选出3*m人,排成m组,每组3人。

    站的队形——较矮的2个人站两侧,最高的站中间。

    从对称学角度来欣赏,左右两个人的身高越接近,则这一组的“残疾程度”越低。

    计算公式为 h=(a-b)^2 (a、b为较矮的2人的身高)
    那么问题来了。

    现在候选人有n个人,要从他们当中选出3*m个人排舞蹈,要求总体的“残疾程度”最低。

    显然是一道动态规划题目。(如果要求最大的残疾程度最小,可以二分解决)

    一道经典的线性动态规划问题,其中也利用了一个贪心的思想。
    核心:相邻最优+倒序处理
    设f[I,j]为前i个人分成j 组的最小值,其中这里的前i个人为高度前i高的人,与题目的前i个人有所不同。
    那么我们有这样的状态转移方程:
    F[I,j]=Min{f[i-1][j], f[i-2][j-1]+(a[i]-a[i-1])^2}
    说明一下:
    1.这里的f[i-1][j]表示不以较矮身份分i号人到组中
    2.f[i-2][j-1]表示以a[i], a[i-1]为两个较矮的人分成一组(即当前此人和后面的一个人一组)
    显然,在排好序后,取a,b时取相邻的总比取不相邻的要好。
    这样我们就可通过计算公式求出“残疾程度”,那么就可以了。
    而f[i-3,j-1]即默认了a[i-2], a[i-1]与a[i]形成一组,实际上残疾程度的计算与最高的人没有任何关系
    所以是f[i-2,j-1]!
    最关键的需要注意DP的方向。。
    由于题目升序排序。。故而当前第i人是最高的。。这样会发生一个很悲剧的情况:
    很有可能最后的几个二元组找不到补齐的第三人。。所以我们需要把数据倒过来处理。。
    即i循环来倒推
    这样就算最后几个人组成若干二元组。。由于n>=3*m成立所以必然可以找到对应的第三人。。
    (这段话好好理解,对dp有很大帮助)
    在有了a,b后,中间的那个人c,需要c>a,c>b,所以c的下标必在a,b前面,又因为a和b相邻
    因此循环的时候要有j<=min(m,(n-i+1)/3)。
    最后答案就是f[1][m]
    嗯表示还是要好好多明白题目意思扩展思路
    涨姿势了Orz
    我写的代码是从后往前倒序的,所以状态转移方程有所不同
    好好体会吧~

    附上AC代码

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    template<class T> inline void read(T &_a){
        bool f=0;int _ch=getchar();_a=0;
        while(_ch<'0' || _ch>'9'){if(_ch=='-')f=1;_ch=getchar();}
        while(_ch>='0' && _ch<='9'){_a=(_a<<1)+(_a<<3)+_ch-'0';_ch=getchar();}
        if(f)_a=-_a;
    }
    
    long long n,m,h[5001],dp[5001][1001];
    
    int main()
    {
        read(m); read(n);
        for (register int i=n;i;--i) read(h[i]);
        memset(dp,0x7f,sizeof(dp));
        for (register int i=1;i<=n;++i) dp[i][0]=0;
        for (register int i=1;i<=n;++i)
            for (register int v=1;v*3<=i&&v<=m;++v)
                dp[i][v]=min(dp[i-1][v],dp[i-2][v-1]+(h[i]-h[i-1])*(h[i]-h[i-1]));
        printf("%lld",dp[n][m]);
        return 0;
    }
  • 相关阅读:
    图文详解k8s自动化持续集成之GitLab CI/CD
    GitLab CI/CD 进行持续集成
    高性能伪事务之Lua in Redis
    面向对象之组合VS继承:继承过时了?
    Go依赖模块版本之Module避坑使用详解
    Maven3路程(三)用Maven创建第一个web项目(1)
    C#通过WIN32 API实现嵌入程序窗体
    Selenium自動化測試(Python+VS2013)-基礎篇-環境安裝
    VS2013中Python学习笔记[环境搭建]
    win7 windows server 2008R2下 https SSL证书安装的搭配(搭配https ssl本地测试环境)
  • 原文地址:https://www.cnblogs.com/jaywang/p/7768643.html
Copyright © 2011-2022 走看看