1. 程式人生 > 其它 >P1103 書本整理

P1103 書本整理

P1103 書本整理

題目描述

Frank是一個非常喜愛整潔的人。他有一大堆書和一個書架,想要把書放在書架上。書架可以放下所有的書,所以Frank首先將書按高度順序排列在書架上。但是Frank發現,由於很多書的寬度不同,所以書看起來還是非常不整齊。於是他決定從中拿掉k本書,使得書架可以看起來整齊一點。

書架的不整齊度是這樣定義的:每兩本書寬度的差的絕對值的和。例如有4本書:

\(1 \times 2\)
\(5 \times 3\)
\(2 \times 4\)
\(3 \times 1\)
那麼Frank將其排列整齊後是:

\(1 \times 2\)
\(2 \times 4\)
\(3 \times 1\)


\(5 \times 3\)
不整齊度就是\(2+3+2=7\)

已知每本書的高度都不一樣,請你求出去掉k本書後的最小的不整齊度。

輸入格式

第一行兩個數字\(n\)\(k\),代表書有幾本,從中去掉幾本。(\(1 \le n \le 100, 1 \le k<n\))

下面的\(n\)行,每行兩個數字表示一本書的高度和寬度,均小於\(200\)

保證高度不重複

輸出格式

一行一個整數,表示書架的最小不整齊度。

樣例 #1

樣例輸入 #1

4 1
1 2
2 4
3 1
5 3

樣例輸出 #1

3

作為開學第一題,感覺自己菜的要死,本來就菜,許久沒刷題更菜了/kk

題目解析

其實是一道很容易看出來的DP,然後我非常sb的堅信可以用貪心解決,只要加一些小小的優化

然後在聽取wa聲一片後才發現是個DP

然後這個思路其實有點巧妙的,我們可以把拿走k本書看作在裡面放入n-k本書

我們這裡f[i][j]表示前i本書裡面拿走j本且第i本必須拿走時的最小不整齊度

看到這裡n<=100,然後我們可以很開心地用O(n^3)的時間複雜度跑完

再注意一些細節即可

程式碼如下

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=105;
struct Node{
  int h,w,_front,_next;
}s[N];
int f[N][N];
int m[N],v[N];
bool cmp(Node x,Node y){
  return x.h<y.h;
}
int main(){
  int n,k;
  scanf("%d%d",&n,&k);
  for(int i=1;i<=n;i++)
    scanf("%d%d",&s[i].h,&s[i].w);
  sort(s+1,s+1+n,cmp);
  memset(f,0x3f,sizeof(f));
  for(int i=1;i<=n;i++){
    f[i][1]=0;
    for(int j=2;j<=min(n-k,i);j++){
      //f[i][j]=0x3f3f3f3f;
      //cout<<f[i][j]<<' ';
      for(int t=1;t<i;t++){
        f[i][j]=min(f[i][j],f[t][j-1]+abs(s[t].w-s[i].w));
      }
      //cout<<f[i][j]<<endl;
    }
  }
  //printf("%d\n",n-k);
  int ans=0x3f3f3f3f;
  for(int i=1;i<=n;i++)ans=min(ans,f[i][n-k]);//,printf("%d\n",f[i][n-k]);
  printf("%d\n",ans);
  return 0;
}