【动态规划】书本整理 book.pas/c/cpp

书本整理(BOOK)

Problem:      book.pas/c/cpp
Input:        book.in
Output:      book.out
Memory Limit:    256 MB
Time Limit:     1 sec

 

【问题描述】

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。

【输出数据】

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

【样例】

book.in

4 1

1 2

2 4

3 1

5 3

 

book.out

3

 

 

 

这一题正着想去去掉几个可能不是怎么好想,所以我们用一下逆向思维

用f[i][j]表示前 i 个数中,留下 j 个数,并且必须留下第 i 个数的最优值

所以   f[i][j]=max{ f[k][j-1]+abs(a[k]-a[i]) }

最后不能直接输出f[n][n-m]!!因为我们定义的是前 i 个数中取 j 个,那么i-1个也可能,i-2个也有可能,所以要在 f[1..n][n-m]中取最优值

C++ Code

/*
C++ Code
http://oijzh.cnblogs.com
By jiangzh
*/
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 110
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))

int n,m;
struct node{int x,y;}a[MAXN];
int f[MAXN][MAXN];//f[i][j]表示前 i 个 留下 j 个 ,并且第 i 个必须留的最优值

bool cmp(node a,node b)
{
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}

int main()
{
    freopen("book.in","r",stdin);
    freopen("book.out","w",stdout);

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
    sort(a+1,a+1+n,cmp);

    memset(f,0x07,sizeof(f));
    for(int i=1;i<=n;i++) f[i][0]=f[i][1]=0;
    for(int j=1;j<=n-m;j++)
        for(int i=1;i<=n;i++)
            for(int k=1;k<i;k++)
                f[i][j]=min(f[i][j],f[k][j-1]+abs(a[k].y-a[i].y));
    int ans=f[n][n-m];
    for(int i=1;i<=n;i++) ans=min(ans,f[i][n-m]);
    printf("%d",ans);
    return 0;
}

  

 

posted @ 2012-11-03 13:44  jiangzh  阅读(785)  评论(0编辑  收藏  举报