清华大学历年考研复试机试真题 - 军训队列

有 n 名学生参加军训,军训的一大重要内容就是走队列,而一个队列的不整齐程度是该队中最高的学生的身高与最矮的学生的身高差值的平方。

现在要将 n 名参加军训的学生分成 k 个队列,每个队列的人数可以是任意非负整数。

在安排队列时希望所有队列的不整齐度之和尽量小,请问不整齐度之和最小可以是多少?

输入格式
第一行两个整数 n,k,表示学生人数和队列数。

第二行 n 个整数,依次表示每名学生的身高。

输出格式
一个整数表示答案。

数据范围
对于10%的数据,k=1;
对于另外10%的数据,k=2;
对于另外10%的数据,k=3;
对于另外10%的数据,k=4;
对于另外10%的数据,1≤n,k≤5;
对于另外10%的数据,1≤n,k≤10;
对于另外20%的数据,1≤n,k≤100;
对于另外5%的数据,n=k=500
对于所有的数据,1≤n,k≤500,0≤ 学生身高 ≤200
输入样例:
3 2
170 180 168
输出样例:
4

//使用dp动态规划 O(n^3) 可以使用斜率优化 新人刚学还不会写 之后来补

#include <stdio.h>
#include <string.h>
#define numMAX 501
#define INF 0x3f3f3f3f 
void quicksort(int a[],int lo,int hi);
int main(){
    int n,k,i,j,p,t,min,a[numMAX];
    scanf("%d %d",&n,&k);
    for(i=1;i<=n;i++) scanf("%d",&a[i]);
    quicksort(a,1,n+1);
    int dp[k+1][n+1];               //dp[i][j] i个队伍j个人时 题目的最小值
    memset(dp,0,sizeof(dp));
    for(i=1;i<=n;i++) dp[1][i]=(a[i]-a[1])*(a[i]-a[1]);
    for(i=2;i<=k;i++){
        for(j=i+1;j<=n;j++){
            min=INF;
            for(p=i-1;p<j;p++){
                t=dp[i-1][p]+(a[j]-a[p+1])*(a[j]-a[p+1]);
                if(t<min) min=t;
            }
            dp[i][j]=min;
        }
    }
    printf("%d",dp[k][n]);
    return 0;
}
void quicksort(int a[],int lo,int hi){
    int n=hi-lo,i=lo,j=hi-1,t=a[lo];
    if(n<=1) return;
    else{
        while(i<j){
            while(i<j && a[j]>=t) j--;
            a[i]=a[j];
            while(i<j && a[i]<=t) i++;
            a[j]=a[i];
        }
        a[i]=t;
        quicksort(a,lo,i);
        quicksort(a,i+1,hi);
    }
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页