zoukankan      html  css  js  c++  java
  • 动态规划之 <筷子>

    描述


    A 先生有很多双筷子。确切的说应该是很多根,因为筷子的长度不一,很难判断出哪两根是一双的。这天,A 先生家里来了K 个客人,A 先生留下他们吃晚饭。加上A 先生,A夫人和他们的孩子小A,共K+3个人。每人需要用一双筷子。A 先生只好清理了一下筷子,共N 根,长度为T1,T2,T3,……,TN。现在他想用这些筷子组合成K+3 双,使每双的筷子长度差的平方和最小。(怎么不是和最小??这要去问A 先生了,呵呵)


    输入


    共有两行,第一行为两个用空格隔开的整数,表示N,K(1≤N≤100,0<K<50),第二行共有N个用空格隔开的整数,为Ti每个整数为1~50之间的数。


    输出


    仅一行。如果凑不齐K+3双,输出-1,否则输出长度差平方和的最小值。


    样例输入


    10 1
    1 1 2 3 3 3 4 6 10 20


    样例输出


    5

    【思路】

        首先应该想到是dp问题。先sort这样第i和第i-1根就是差距最小的了,

        f[i][j]表示前i根组成j双筷子每双长度差的和的最小值。

       在考虑第i根筷子时,需要做出的决策即使要不要把这只筷子加入到最优解中去,

       若加入,则其与第(i-1)根筷子组成一对,f[i][j]=f[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]),否则f[i][j]=f[i-1][j] . 


       当然,上述决策过程依赖于以下先验知识:

        当从小到大排好的 a,b,c,d 四根筷子组成两双时, ab,cd 这样的组合最优. 就是以上决策时采取的 将第i个筷子跟第i-1根组成一对.


       故dp方程这样写

      f[i][j]=min(f[i-1][j],f[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]));


    【代码】

     

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<climits>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int  f[200][200],a[200];
    int n,k,i,j;
    int min(int a,int b)
    {
        if(a<b)
            return a;
        else
            return b;
    }
    void init()
    {
     scanf("%d%d",&n,&k);
     if((k+3)*2>n)cout<<-1<<endl,exit(0);
     for(i=1;i<=n;i++)
     scanf("%d",&a[i]);
     sort(&a[1],&a[n]+1);
    }
    int main()
    {
      init();
      memset(f,0x3f,sizeof(f));
      for(i=0;i<=n;i++)f[i][0]=0;
      for(i=2;i<=n;i++)    
      for(j=1;j<=i/2;j++)
      f[i][j]=min(f[i-1][j],f[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]));
     
      printf("%d ",f[n][k+3]);
      return 0;
    }




  • 相关阅读:
    mongodb 聚类查询 筛选时间
    异步线程
    性能优化
    何谓引继(引继码,继承码)?了解引继同备份不同,请注意!
    apktool 无法识别 requestLegacyExternalStorage 属性导致回编失败
    Jenkins GIT_SSH组件权限导致build失败的问题。
    Linux下 Nginx-uWSGI-Django 搭建
    SSH scp使用
    Django创建app及创建数据库
    正则表达式
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3424207.html
Copyright © 2011-2022 走看看