P1103 书本整理 题解

CSDN同步

原题链接

简要题意:

给定 (n) 个二元组 ({x,y}),你的任务首先要将它们按照 (x) 排序(保证 (x) 两两不同),然后从中去掉 (k) 个二元组,使得 剩下的每相邻二元组 (y) 的差的绝对值之和最小,求这个最小值。

(n leq 100 , x,y leq 200).

原题中书的高度即为 (x),书的宽度即为 (y).

首先我们建立结构体 ( ext{book {height , width}}) 来存储每一本书的情况,便于排序操作。其次我们考虑,类似 (n space ext{choose} space k) 的做法,数据范围很弱,考虑用 动态规划 做。

考虑反其道而行之,去掉 (k) 个也就是反选 (n-k) 个,换成了熟悉的形式。用 (f_{i,j}) 表示前 (i) 本书选 (j) 本(必须选第 (i) 本)的最优答案。

这样很容易得到:

[f_{i,l} = egin{cases} 0 space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space space , l = 1 \ min_{j=1}^i f_{j,l-1} + |a_i . ext{width} - a_j . ext{width}| , l > 1\ end{cases}]

第一行是边界条件,很显然选 (1) 个肯定是 (0). 其余情况枚举从那里开始选就可以了。

时间复杂度:(mathcal{O}(n^3)).

实际得分:(100pts).

// 其实不用开 long long , 特此注明
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N=1e2+1; 

inline int read(){char ch=getchar(); int f=1; while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
	int x=0; while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f;}

inline void write(int x) {
	if(x<0) {putchar('-');write(-x);return;}
	if(x<10) {putchar(char(x%10+'0'));return;}
	write(x/10);putchar(char(x%10+'0'));
}

struct book {
	int height,width;
} a[N]; int n,k; 
ll f[N][N];

inline bool cmp(book x,book y) {
	return x.height<y.height;
}

int main() {
	n=read(),k=read();
	for(int i=1;i<=n;i++) a[i].height=read(),a[i].width=read();
	sort(a+1,a+1+n,cmp);
	memset(f,127,sizeof(f));
	for(int i=0;i<=n;i++) f[i][1]=0ll; //初始化极大值和边界
	for(int i=2;i<=n;i++) for(int j=1;j<i;j++)
	for(int l=2;l<=min(i,n-k);l++)
		f[i][l]=min(f[i][l],f[j][l-1]+abs(a[i].width-a[j].width)); //转移操作
	ll ans=(1ll<<62);
	for(int i=n-k;i<=n;i++) ans=min(ans,f[i][n-k]); //统计答案
	printf("%lld
",ans);
	return 0;
}


原文地址:https://www.cnblogs.com/bifanwen/p/13669678.html