书本整理

来源:互联网 发布:百度经验赚钱 知乎 编辑:程序博客网 时间:2024/04/27 13:51

书本整理(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     http://blog.csdn.net/jiangzh7     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;      }  


0 0
原创粉丝点击