动态规划之 筷子

news/2025/2/26 11:27:00

描述


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\n",f[n][k+3]);
  return 0;
}


 

 



 


http://www.niftyadmin.cn/n/989473.html

相关文章

动态规划优化

状态优化 bzoj2064 分裂 存在通解&#xff1a;把原始集合都合并&#xff0c;再一一拆开。 如果可以划分一些集合&#xff0c;使得原始集合和目标集合对应的小集合相等&#xff0c;那么可以节省操作次数。 ans(n1-1)(n2-1)-2*(x-1) x为划分的相同集合数。 n<10,状压 另外&…

[讽刺笑话] 移动公司老板与公厕老大爷的经典对白

超强的移动公司老板与公厕老大爷的经典对白今天早上&#xff0c;移动公司某经理在外突然感觉内急&#xff0c;只好找公共厕所。“干什么的&#xff1f;”大爷喊。“我是移动老总&#xff0c;我内急。”经理。“你不知道现在什么都要收费啊&#xff1f;”大爷。“行&#xff0c;…

关于SD-WAN,你想知道的都在这里

SD-WAN是什么&#xff1f;SD-WAN&#xff0c;即软件定义广域网络&#xff0c;是将SDN/NFV/Cloud等技术应用到广域网中所形成的一种网络服务。这种服务通常用于连接不同区域的企业分支机构、数据中心、公有云等。SD-WAN出现背景随着“互联网”的深入推进&#xff0c;企业数字化进…

#那些年写过的搓程序#shell里的位数判断

当年为了输出000到120每隔6小时一张预报图&#xff0c;用000,006,120这样的规则命名&#xff0c;我写了以下的搓程序&#xff1a; for ((i0;i<120;ii6)) do if [ $i -le 9 ] then ii00$i elif [ $i -le 99 ] then ii0$i else ii$i fi done 直到我找到了print才发现上面这11行…

Windows Server 部署DNS服务

Windows Server 部署DNS服务 当我们在上网的时候&#xff0c;通常输入的是网址&#xff0c;其实这就是一个域名&#xff0c;而我们计算机网络上的计算机彼此之间只能用I P地址才能相互识别。域名&#xff08;网址&#xff09;只是相当与门牌号&#xff0c;只是为了方便记忆而增…

【js】this问题

var obj {a: 10,b: () > {console.log(this.a); // undefinedconsole.log(this); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}},c: function () {console.log(this.a); // 10console.log(this); // {a: 10, b: ƒ, c: ƒ}} } obj.b(…

WOW插件:ChatFormat 0.11 发布

---------------------------------ChatFormat 0.11-------------------------------------- 下载&#xff1a;/Files/simonw/ChatFormat.rar作者&#xff1a;simonw, [2区 暗影之月 人类牧师 民族英雄]Email:&#xff1a;i-simon AT msn.comWebSite&#xff1a;http://www.cnb…

访问共享盘,无法访问,您可能没有权限使用网络资源,请与这台服务器的管理员联系以查明您是否有访问权限。...

2019独角兽企业重金招聘Python工程师标准>>> 访问共享盘&#xff0c;出现如下错误&#xff1a; 原因&#xff1a;以前访问的时候记住了用户名密码&#xff0c;这次访问的时候使用了另一个密码进行访问&#xff0c;就会出现这样的问题。 解决方案 1&#xff1a;使用n…