动态规划之 <筷子>
描述
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<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;
}
动态规划之 <筷子>的更多相关文章
- caioj 1077 动态规划入门(非常规DP1:筷子)
首先可以看出排序之后,最优解肯定是每一对都相邻才是最优的 那么我们就要找构成最优解的相邻组 设f[i][j]是前i个字符,k对的最小值 如果当前这个筷子不取的话,f[i][j] = f[i-1][j] ...
- 增强学习(三)----- MDP的动态规划解法
上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...
- 简单动态规划-LeetCode198
题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...
- 动态规划 Dynamic Programming
March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...
- 动态规划之最长公共子序列(LCS)
转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...
- C#动态规划查找两个字符串最大子串
//动态规划查找两个字符串最大子串 public static string lcs(string word1, string word2) { ...
- C#递归、动态规划计算斐波那契数列
//递归 public static long recurFib(int num) { if (num < 2) ...
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- 【BZOJ1700】[Usaco2007 Jan]Problem Solving 解题 动态规划
[BZOJ1700][Usaco2007 Jan]Problem Solving 解题 Description 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地 ...
随机推荐
- hdu3015树状数组 poj1990的离散化版本
都是一类题目,推导调试比较烦,想出来还是不难的 /* 给定n个点对,按一维升序排序一次,每个点的序号为Di,按二维升序排序一次,每个点的序号为Hi 求sum{w(i,j)} w(i,j)=abs(Di ...
- 性能测试三:jmeter进阶之图形插件
一.图形化插件的使用 使用Jmeter插件可以更直观的查看tps和响应时间 插件官网: http://jmeter-plugins.org/downloads/all 第一种方法,找到需要的插件下载j ...
- python接口自动化测试十七:使用bs4框架进行简单的爬虫
安装:beautifulsoup4 from bs4 import BeautifulSoup yoyo = open('yoyo.html', 'r') # 以读的方式打开“yoyo.html” ...
- DBMS_OUTPUT包学习
DBMS_OUTPUT包中的其他方法和函数的用法,所以这次特地来研究一下. 先简单的讲解一下这个包的所有procedure的含义及作用: ----------------------- 1. ...
- POJ 2184 Cow Exhibition (带负值的01背包)
题意:给你N(N<=100)只牛,每只牛有一个智慧值Si和一个活泼值Fi,现在要从中找出一些来,使得这些牛智慧值总和S与活泼值总和F之和最大,且F和S均为正.Si和Fi范围在-1000到1000 ...
- C# 使用委托实现多线程调用窗体的四种方式
1.方法一:使用线程 功能描述:在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线程,如果不采用多线程控制进度条,窗口 ...
- mysql数据库备份 mysqldump
一.--all-databases /application/mysql3307/bin/mysqldump -uroot -S /application/mysql3307/logs/mysql.s ...
- Ajax提交form表单内容和文件(jQuery.form.js)
jQuery官网是这样介绍form.js A simple way to AJAX-ify any form on your page; with file upload and progress s ...
- Selenium 获取文本信息方法+select(定位)
1.通过先定位到具体的元素然后通过text方法获取文本信息,如获取控件名称等 driver.find_element_by_xpath("//div[/h1").text 2.直接 ...
- ModuleNotFoundError: No module named 'win32api'
原因:缺少了win32解决: pip install pypiwin32