zoukankan      html  css  js  c++  java
  • 羊羊列队

    羊羊列队

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 65  解决: 1
    [提交][状态][讨论版]

    题目描述

    在修建完新路后,小羊们总算可以安心入学了。今年是羊年,新入学的小羊特别多。老师们打算将N只小羊分成M个班级,每个班至少有1只羊。

    如何分班成了老师们最头疼的事情,因为开学典礼上,村长就要看到小羊们列队的情况。每个班的小羊都排成一排,站在草场上。村长希望队列中羊的高度尽可能整齐,村长对队列的不整齐度有自己的要求。

    例如队列中共有t只羊,高度依次为A1,A2……,At。那么不整齐度为:(|A1-A2|+|A2-A3|+……+|At-1-At|)2。即相邻两只羊高度差之和的平方。

    而总体的不整齐度,就是各班不整齐度之和。

    现在,请你帮助老师们设计一下,如何分班,如何列队,才能使M个班级的不整齐度之和最小。

    输入

    第一行两个整数N和M,分别表示共有N只小羊,要被分成M个班级。

    第二行N个整数,表示每只小羊的高度Ai。

    输出

    输出最小的不整齐度之和,结果保证不会超过231-1。

    样例输入

    4 2

    4 1 3 2

    样例输出

    2

    提示
    【样例解释】
    分成两班,4和3一个班,1和2一个班,不管怎么排,两个班的不整齐度都是1,不整齐度之和为2。
    【数据范围】
    30%的数据,1<=N<=10;1<=M<=5;
    80%的数据,1<=N<=300;1<=Ai<=1000;
    100%的数据,1<=N<=10000,1<=M<=1000,1<=Ai<=1000000,保证M<=N。

     

    思路:

    /*
    * s[i][j]表示第i只小羊到第j只小羊的不整齐度
    * 分析:
    * 状态:
    * f[i][j]表示把i只小羊分到j个班级的最小不整齐度。
    * 初始状态:
    * f[i][1]=s[1][i],f[i][i]=0,f[i][0]=0,f[0][i]=0;
    * 最终状态:
    * f[n][m]
    * 状态转移方程:
    * k表示两个班级划分的点
    * f[i][j]=min(f[i][j],f[k][j-1]+s[k+1][i]) (j-1<=k<i)
    *
    * dp过程:
    * i...1->n
    * j...i->i
    * k...j-1->i-1
    *
    */

      1 /*
      2  * s[i][j]表示第i只小羊到第j只小羊的不整齐度
      3  * 分析:
      4  * 状态:
      5  * f[i][j]表示把i只小羊分到j个班级的最小不整齐度。
      6  * 初始状态:
      7  * f[i][1]=s[1][i],f[i][i]=0,f[i][0]=0,f[0][i]=0;
      8  * 最终状态:
      9  * f[n][m]
     10  * 状态转移方程:
     11  * k表示两个班级划分的点
     12  * f[i][j]=min(f[i][j],f[k][j-1]+s[k+1][i]) (j-1<=k<i)
     13  *
     14  * dp过程:
     15  * i...1->n
     16  * j...i->i
     17  * k...j-1->i-1
     18  *
     19  */
     20 #include <bits/stdc++.h>
     21 #define Maxn 305
     22 #define Maxm 305
     23 using namespace std;
     24 void printArr_a();
     25 void printArr_s();
     26 void printArr_f();
     27 void printArr_k_();
     28 void printArr_classCheep();
     29 void printArr_pre();
     30 void printWay(int i,int j);
     31 int f[Maxn][Maxm],a[Maxn],s[Maxn][Maxn];
     32 int pre[Maxn][Maxm];
     33 int k_[Maxn];//决策
     34 int classCheep[Maxn][2];//每个班级里面的人数
     35 int n,m;
     36 //s[i][j]表示第i只小羊到第j只小羊的不整齐度
     37 int main(){
     38     freopen("src/in.txt","r",stdin);
     39     cin>>n>>m;
     40     for(int i=1;i<=n;i++) cin>>a[i];
     41     sort(a+1,a+n+1);
     42     //printArr_a();
     43     //初始化s数组
     44     for(int i=1;i<=n;i++){
     45         s[i][i]=0;
     46         int tmp=0;
     47         for(int j=i+1;j<=n;j++){
     48             tmp+=a[j]-a[j-1];
     49             s[i][j]=tmp*tmp;
     50         }
     51     }
     52     //printArr_s();
     53     //dp操作
     54     //------------------------------------------------------------
     55     memset(f,0x1f,sizeof(f));
     56 
     57     //初始化
     58     for(int i=0;i<=n;i++){
     59         f[i][1]=s[1][i];
     60         f[i][i]=0;
     61         f[i][0]=0;
     62         f[0][i]=0;
     63         for(int j=i+1;j<=n;j++){
     64             f[i][j]=0;
     65         }
     66     }
     67     //printArr_f();
     68     for(int i=2;i<=n;i++){
     69         for(int j=2;j<=m&&j<i;j++){
     70             for(int k=j-1;k<i;k++){
     71                 //f[i][j]=min(f[i][j],f[k][j-1]+s[k+1][i]);
     72                 int tmp=f[k][j-1]+s[k+1][i];
     73                 if(tmp<f[i][j]){
     74                     f[i][j]=tmp;
     75                     k_[i]=k;
     76                     pre[i][j]=k;
     77                     classCheep[i][0]=k+1;
     78                     classCheep[i][1]=i;
     79                 }
     80             }
     81         }
     82     }
     83 //    printArr_f();
     84 //    printArr_k_();
     85 //    printArr_classCheep();
     86 //    printArr_pre();
     87 //    printWay(9,4);
     88     cout<<f[n][m]<<endl;
     89 }
     90 
     91 
     92 
     93 void printArr_a(){
     94     cout<<"Arr_a"<<endl;
     95     for(int i=1;i<=n;i++){
     96         cout<<a[i]<<" ";
     97     }
     98     cout<<endl;
     99 }
    100 void printArr_s(){
    101     cout<<"Arr_s"<<endl;
    102     for(int i=1;i<=n;i++){
    103         for(int j=1;j<=n;j++){
    104             cout<<setw(5)<<s[i][j]<<" ";
    105         }
    106         cout<<endl;
    107     }
    108 }
    109 void printArr_f(){
    110     cout<<"Arr_f"<<endl;
    111     for(int i=0;i<=n;i++){
    112         for(int j=0;j<=m;j++){
    113             cout<<setw(12)<<f[i][j]<<" ";
    114         }
    115         cout<<endl;
    116     }
    117 }
    118 void printArr_k_(){
    119     cout<<"Arr_k_"<<endl;
    120     for(int i=1;i<=n;i++){
    121         cout<<k_[i]<<" ";
    122     }
    123     cout<<endl;
    124 }
    125 void printArr_classCheep(){
    126     cout<<"Arr_classCheep"<<endl;
    127     for(int i=1;i<=n;i++){
    128         cout<<""<<i<<"只羊:    "<<classCheep[i][0]<<" "<<classCheep[i][1]<<endl;
    129     }
    130     cout<<endl;
    131 }
    132 
    133 void printArr_pre(){
    134     cout<<"Arr_pre"<<endl;
    135     for(int i=0;i<=n;i++){
    136         for(int j=0;j<=m;j++){
    137             cout<<setw(12)<<pre[i][j]<<" ";
    138         }
    139         cout<<endl;
    140     }
    141 }
    142 
    143 void printWay(int i,int j){
    144     if(j==0) return;
    145     printWay(pre[i][j],j-1);
    146     int start=pre[i][j]+1;
    147     int end=i;
    148     int k=0;
    149     while(end-start){
    150         cout<<a[start++]<<" ";
    151     }
    152     cout<<a[end]<<endl;
    153 }
  • 相关阅读:
    2015 年最受 Linux 爱好者欢迎的软硬件大盘点
    Java 9终于要包含Jigsaw项目了
    Linux 容器技术史话:从 chroot 到未来
    开发者最常用的 8 款 Sublime Text 3 插件
    60,000毫秒内对Linux的性能诊断效的方法
    bzoj 2595 [Wc2008]游览计划(斯坦纳树)
    bzoj 3997 [TJOI2015]组合数学(DP)
    bzoj 1014 [JSOI2008]火星人prefix(splay+hash)
    bzoj 1090 [SCOI2003]字符串折叠(区间DP)
    bzoj 1537 [POI2005]Aut- The Bus(DP+BIT)
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7421140.html
Copyright © 2011-2022 走看看