P1103 書本整理
阿新 • • 發佈:2022-12-13
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; }