书本整理
题目描述
Frank
是一个非常喜爱整洁的人。他有一大堆书和一个书架,想要把书放在书架上。书架可以放下所有的书,所以Frank
首先将书按高度顺序排列在书架上。但是Frank
发现,由于很多书的宽度不同,所以书看起来还是非常不整齐。于是他决定从中拿掉k本书,使得书架可以看起来整齐一点。
书架的不整齐度是这样定义的:每两本书宽度的差的绝对值的和。例如有4本书:
1 imes 21×2
5 imes 35×3
2 imes 42×4
3 imes 13×1
那么Frank
将其排列整齐后是:
1 imes 21×2
2 imes 42×4
3 imes 13×1
5 imes 35×3
不整齐度就是2+3+2=72+3+2=7
已知每本书的高度都不一样,请你求出去掉k本书后的最小的不整齐度。
输入格式
第一行两个数字nn和kk,代表书有几本,从中去掉几本。(1 le n le 100, 1 le k<n1≤n≤100,1≤k<n)
下面的nn行,每行两个数字表示一本书的高度和宽度,均小于200200。
保证高度不重复
输出格式
一行一个整数,表示书架的最小不整齐度。
输入输出样例
输入 #1
4 1 1 2 2 4 3 1 5 3
输出 #1
3
题目分析:
对于一列书,如果我们直接按照题目模拟,会发现过程比较困难,因为如果抽出一本书,就要计算与之相邻的两本书之间的差以及这本书与他相邻元素的绝对值的差,不好模拟,所以我们考虑倒叙存入,从这些书中选择一本书依次插入队列。两种情况:
一、自己是对头,对于答案的贡献是0
二、从已经选择过的书的后面插入,对于答案的贡献就是当前书与选择插入的书的绝对值的差
循环判断即可。
AC代码:
#include<bits/stdc++.h> using namespace std; int f[302][302]; int n,m; struct node{ int a,h; }v[502]; bool cmp(node a,node b) { return a.h <b.h ; } int main() { cin>>n>>m; m=n-m; for(int i=1;i<=n;i++) { cin>>v[i].h >>v[i].a ; } sort(v+1,v+1+n,cmp); memset(f,0x3f,sizeof(f)); for(int i=1;i<=n;i++) f[i][1]=0; for(int i=2;i<=n;i++) { for(int j=1;j<=i-1;j++) { for(int l=2;l<=min(i,m);l++) { f[i][l]=min(f[i][l],f[j][l-1]+abs(v[i].a -v[j].a )); } } } int ans=99999; for(int i=m;i<=n;i++) { ans=min(ans,f[i][m]); } cout<<ans<<' '; return 0; }