洛谷P1103 书本整理

来源:互联网 发布:linux vim删除多行 编辑:程序博客网 时间:2024/04/27 17:05

题目描述

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

但看去掉几本书是不好写方程的,看成从 n 本书里挑 n - k 本,那么转移方程就是 f [ i ][ j ] = min( f [ i ] [ j ] , f[ k ][ j-1 ] + abs( num[i] - num[k])); f [ i ][ j ] 为前 i 本书选 j 本且第 i 本选上的最小代价,初始化的话, f [ i ][ 1 ] = 0;
代码如下

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int size = 210;int read(){    int x = 0 , f = 1;    char in = getchar();    while(in < '0' || in > '9')    {        if(in == '-')            f = -1;        in = getchar();    }    while(in >= '0' && in <= '9')    {        x = x * 10 + in - '0';        in = getchar();    }    return x * f;}struct book{    int r,c;    bool operator <(const book &a)const    {        return r < a.r;    }}b[size];int num[size];int n,p;int f[size][size];int main(){    scanf("%d%d",&n,&p);    for(int i = 1 ; i <= n ; i ++)        b[i].r = read() , b[i].c = read();    sort(b+1,b+n+1);    for(int i = 1 ; i <= n ; i ++)        num[i] = b[i].c;    memset(f,63,sizeof(f));    for(int i = 1 ; i <= n ; i ++)        f[i][1] = 0;    for(int i = 1 ; i <= n ; i ++)        for(int j = 2 ; j <= n - p ; j ++)            for(int k = 1 ; k < i ; k ++)                f[i][j] = min(f[i][j],f[k][j-1]+abs(num[i]-num[k]));    int ans = 2147483641;    for(int i = 1 ; i <= n ; i ++)        ans = min(f[i][n-p],ans);    printf("%d\n",ans);    return 0;}
1 0
原创粉丝点击