【动态规划】书本整理 book.pas/c/cpp
书本整理(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
/* C++ Code http://oijzh.cnblogs.com 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; }
..... 转载请注明出处 ..... http://oijzh.cnblogs.com ..... by jiangzh