洛谷 P1103 书本整理

题目描述

Frank是一个非常喜爱整洁的人。他有一大堆书和一个书架,想要把书放在书架上。书架可以放下所有的书,所以Frank首先将书按高度顺序排列在书架上。但是Frank发现,由于很多书的宽度不同,所以书看起来还是非常不整齐。于是他决定从中拿掉k本书,使得书架可以看起来整齐一点。

书架的不整齐度是这样定义的:每两本书宽度的差的绝对值的和。例如有4本书:

1x2 5x3 2x4 3x1 那么Frank将其排列整齐后是:

1x2 2x4 3x1 5x3 不整齐度就是2+3+2=7

已知每本书的高度都不一样,请你求出去掉k本书后的最小的不整齐度。

输入输出格式

输入格式:

 

第一行两个数字n和k,代表书有几本,从中去掉几本。(1<=n<=100, 1<=k<n)

下面的n行,每行两个数字表示一本书的高度和宽度,均小于200。

保证高度不重复

 


输出格式:

 

一行一个整数,表示书架的最小不整齐度。

 

输入输出样例

输入样例#1:
4 11 22 43 15 3
输出样例#1:
3

题解:

f[i][j]: 在考虑前i个时拿走j本且i必保留时的最优解

 
状态转移方程
 
f[i][j]=f[l=(i-j-1 to i-1)][j-(i-l-1)]+|a[i]-a[l]|
 
前i个时拿走j本且i必保留时的最优解,他当然可以是在
前l个中拿一些书并把l到i间的书全拿走造成的;
 
即,前i个时拿走j本且i必保留时的最优解,为前l(找出这个l)
个时拿走j-(i-l-1)本且l必保留时的最优解,加i与l的差;
 
然后在合适的区间内(i-j-1 to i-1)循环l使之最优;
 
 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
struct bo{
int a,b;
}s[];
int comp(const bo& x,const bo& y)
{
if(x.a<y.a)
return ;
return ;
}
int n,k,f[][],a[][],minn=;
int main(){
cin>>n>>k;
for(int i=;i<=n;i++)
cin>>s[i].a>>s[i].b;
sort(s+,s++n,comp); for(int i=;i<=n;i++)
f[i][]=;
for(int i=;i<=n;i++)
for(int j=;j<=min(i,n-k);j++)
{f[i][j]=; for(int x=j-;x<=i-;x++)
{
f[i][j]=min(f[i][j],f[x][j-]+abs(s[i].b-s[x].b));
}}
for(int i=n-k;i<=n;i++)
{minn=min(minn,f[i][n-k]);
}
cout<<minn;
}
 
05-11 22:49