zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:军训队列(DP+乱搞)

    题目描述

    有$n$名学生参加军训,军训的一大重要内容就是走队列,而一个队列的不规整程度是该队中最高的学生的身高与最矮的学生的身高差值的平方。
    现在要将$n$名参加军训的学生重新分成$k$个队列,每个队列的人数不限,请求出所有队列的不规整程度之和的最小值。


    输入格式

    第一行两个整数$n,k$,表示学生人数和队列数。
    第二行$n$个实数,表示每名学生的身高。身高范围在$140sim 200cm$之间,保留两位小数。


    输出格式

    一个实数表示答案,保留$2$位小数。


    样例

    样例输入1:

    3 2
    170.00 180.00 168.00

    样例输出1:

    4.00

    样例输入2:

    5 2
    170.00 180.00 168.00 140.59 199.99

    样例输出2:

    1023.36


    数据范围与提示


    题解

    $50$分的$DP$应该都会打,问题就在于如何优化。

    的确可以斜率优化,但是考虑身高的范围,也就是说最多有$6000$种不同的身高。

    那么离散化一下不就$AC$啦?

    再考虑另一种并不正确的算法,尽可能让平方差最大的一组最小;的确是错的,第二个样例都过不了,但是在数据范围比较大的时候很难被卡;再结合前面暴力$DP$即可拿到满分……

    时间复杂度:$Theta(6000 imes 6000)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int n,k;
    double h[100001];
    double dp[100001][21];
    double ans=1000000000.0;
    int main()
    {
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++)scanf("%lf",&h[i]);
    	sort(h+1,h+n+1);
    	n=unique(h+1,h+n+1)-h-1;
    	for(int i=1;i<=n;i++)dp[i][1]=(h[i]-h[1])*(h[i]-h[1]);
    	for(int j=2;j<=k;j++)
    		for(int i=1;i<=n;i++)
    		{
    			dp[i][j]=10000000000.0;
    			for(int l=i;l>=j;l--)
    				dp[i][j]=min(dp[i][j],dp[l-1][j-1]+(h[i]-h[l])*(h[i]-h[l]));
    		}
    	printf("%.2lf",dp[n][min(n,k)]);
    	return 0;
    }
    

    rp++

  • 相关阅读:
    how to uninstall devkit
    asp.net中bin目录下的 dll.refresh文件
    查找2个分支的共同父节点
    Three ways to do WCF instance management
    WCF Concurrency (Single, Multiple, and Reentrant) and Throttling
    检查string是否为double
    How to hide TabPage from TabControl
    获取当前系统中的时区
    git svn cygwin_exception
    lodoop打印控制具体解释
  • 原文地址:https://www.cnblogs.com/wzc521/p/11746874.html
Copyright © 2011-2022 走看看