[dp] uva10271 Chopsticks
来源:互联网 发布:python write 编辑:程序博客网 时间:2024/06/07 10:10
Description
In China, people use a pair of chopsticks to get food on the table, but Mr. L is a bit different. He uses a set of three chopsticks – one pair, plus an EXTRA long chopstick to get some big food by piercing it through the food. As you may guess, *the length of the two shorter chopsticks should be as close as possible, but the length of the extra one is not important, as long as it’s the longest. To make things clearer, for the set of chopsticks with lengths A B C (A ≤ B ≤ C), (A − B)2 is called the “*badness” of the set.
It’s December 2nd, Mr.L’s birthday! He invited K people to join his birthday party, and would like to introduce his way of using chopsticks. So, he should prepare K + 8 sets of chopsticks(for himself,his wife, his little son, little daughter, his mother, father, mother-in-law, father-in-law, and K other guests). But Mr.L suddenly discovered that his chopsticks are of quite different lengths! He should find a way of composing the K + 8 sets, so that the total badness of all the sets is minimized.
Input
The first line in the input contains a single integer T , indicating the number of test cases (1 ≤ T ≤ 20). Each test case begins with two integers K, N (0 ≤ K ≤ 1000, 3K + 24 ≤ N ≤ 5000), the number of guests and the number of chopsticks.There are N positive integers on the next line in non–decreasing order indicating the lengths of the chopsticks(1 ≤ Li ≤ 2000) .
Output
For each test case in the input, print a line containing the minimal total badness of all the sets.Note: For the sample input, a possible collection of the 9 sets is:
8,10,16; 19,22,27; 61,63,75; 71,72,88; 81,81,84; 96,98,103; 128,129,148; 134,134,139; 157,157,160
Sample Input
1
1 40
1 8 10 16 19 22 27 33 36 40 47 52 56 61 63 71 72 75 81 81 84 88 96 98 103 110 113 118 124 128 129 134 134 139 148 157 157 160 162 164
Sample Output
23
题目分析
先考虑一个更简单的问题:将一组筷子改为两双。定义f[i][j]为前j根筷子组成i组的”the minimal total badness of all the sets”。由于筷子长度组成不减序列,故一组筷子中的两根必定相邻。考虑第j根筷子,它有两种可能:在或不在第i组中。因此得到状态转移方程:
f[i][j]=min(f[i][j-1],f[i-1][j-2])
然后考虑此题,一组筷子为三双,最长的一根在计算中没有充当作用,因此只需倒序读入,使筷子形成不增序列,即可忽略其产生的影响,状态转移方程没有变化。
但此处可能有个疑问,对于f[i][j](j>3*i),有没有可能选出了i组的两根筷子,余下的j-i根不足以挑出较长的i根。举例来说,有没有可能选出以下不合法策略?
这是不会出现的,看转移方程
f[i][j]=min(f[i][j-1],f[i-1][j-2])
对于前一种策略,它依赖于以前的f[i][j-1],只要f[i][j-1]策略合法,此策略也合法;对于后一种策略,由于此为单调不增序列,最后两根一定最短,也是合法的。
最后注意循环时j>=3*i。
代码
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>using namespace std;const int maxn=5001;int a[maxn];int f[1009][maxn];int ds[maxn];int min(int,int);int main(){ int t; cin>>t; while(t--) { int k,n; cin>>k>>n; k+=8; for(int i=n;i>=1;i--) scanf("%d",&a[i]); for(int i=2;i<=n;i++) ds[i]=(a[i]-a[i-1])*(a[i]-a[i-1]); memset(f,0x6f,sizeof f); memset(f[0],0,sizeof f[0]); for(int i=1;i<=k;i++) { for(int j=i*3;j<=n;j++) f[i][j]=min(f[i][j-1],f[i-1][j-2]+ds[j]); } cout<<f[k][n]<<endl; } return 0;}int min(int a,int b){return (a<b)?a:b;}
- [dp] uva10271 Chopsticks
- uva10271 - Chopsticks
- UVA10271- Chopsticks
- UVA10271【Chopsticks】
- uva10271 - Chopsticks(巧妙动归)
- uva10271 - Chopsticks(递推)
- uva10271(DP)
- dp(uva10271)
- uva10271 经典DP
- uva10271
- uva10271
- hdoj 1500 Chopsticks(DP)
- zju 1234 Chopsticks (DP)
- uva_10271 - Chopsticks (普通DP)
- UVa 10271 - Chopsticks dp
- UVA 10271 Chopsticks(dp)
- uva 10271 Chopsticks(dp)
- HDU-1500 Chopsticks DP
- Ubuntu Linux 查看、编辑、比较二进制文件
- 反射相关知识
- QT SSL OpenSSL https
- 计算机视觉中的边缘检测
- Ios本地通知Notification的使用
- [dp] uva10271 Chopsticks
- android Graphics(三):区域(Range)
- C++返回table给lua
- web.xml配置解析
- spring整合hibernate配置文件
- Node.js 初识
- 【网络】HTTP协议的头信息详解
- list数据类型
- java switch语句缺少break跳转之后的算法原理