1. 程式人生 > >【Luogu】P1103 書本整理の心得

【Luogu】P1103 書本整理の心得

bsp 一點 代碼 cin 最小 () struct space math.h

傳送門qwq

  卡了好長時間,結果發現是一道普及的題,啪啪啪啪啪。。。。。

  雖然dp方程不難想,但是思路還是很重要的,**轉化題意**是最重要的一步,例如,抽調k本書,可以轉化為在n本書裏選擇n-k本書,而不是去寫sb的3維區間dp,而且根本不可寫23333,另外,dp得到的dp[n][n-k]不一定就是答案,要註意到,並不一定最後一本選的書是第n本,所以一定要把dp數組掃一下,再得出最優解!!

  dp[i][j]表示在最後一本書為i時,一共選了j本書的最小值。

           dp[i][j]=min(dp[i][j],dp[x][j-1])


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

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

1x2 5x3 2x4 3x1 那麽Frank將其排列整齊後是:

1x2 2x4 3x1 5x3 不整齊度就是2+3+2=7

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

附上代碼

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<math.h>
using namespace std;
struct nod{
    
int h; int w; }; nod b[105]; int dp[105][105]; inline int cmp(nod a,nod b){ return a.h<b.h; } int main(){ int n,k; cin>>n>>k; for(register int i=1;i<=n;i++){ cin>>b[i].h>>b[i].w; } sort(b+1,b+n+1,cmp); for(register int i=0;i<=n;i++){
for(register int j=0;j<=n;j++){ dp[i][j]=99999999; } dp[i][0]=0; dp[i][1]=0; } for(register int x=2;x<=n-k;x++){ for(register int i=1;i<=n;i++){ if(i<x)continue; for(register int j=i-1;j>=x-1;j--){ dp[i][x]=min(dp[j][x-1]+(int)fabs(b[i].w-b[j].w),dp[i][x]); //cout<<dp[j][x-1]<<‘ ‘<<(int)fabs(b[i].w-b[j].w)<<‘ ‘<<dp[i][x]<<endl; //cout<<i<<‘ ‘<<j<<‘ ‘<<x<<endl<<endl; } } } int ans=99999999; for(int i=n-k;i<=n;i++){ ans=min(ans,dp[i][n-k]); } cout<<ans<<endl; }

【Luogu】P1103 書本整理の心得