码迷,mamicode.com
首页 > 其他好文 > 详细

P1103 书本整理

时间:2020-03-24 12:37:54      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:去掉   还需   排序   代码   names   print   决定   ace   ++   

题意:给出n本书 每本书有高度和宽度,题意让我们先讲高度排序(保证每一本书的高度不同,从大从小排对答案不影响)

     相邻的书的宽度差的绝对值为贡献,让我们去掉其中k本书,求最小贡献

思路:去掉书的想法很难实现,我们逆向思维,在其中增加n-k本书

     那我们设定一个dp【i】【j】表示第i本书前面的所有书(包括第i本)选择j本情况下的最优值

        那么答案就应该是从(n-k,n)选择一个最优值,因为我们是在某一本必选的情况下选择的最优

          所以在不选这本的情况下可能不是最优,所以最后还需要再枚举一遍哪个最优

             这是最后一部分,我们再来讲讲前面一部分

                在枚举前i本书的情况下,我们再开一维来枚举前i本书放L本的情况

                  然后再枚举放L本时的最优值即可

代码如下:

  

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,k,m,Min=0x3f3f3f3f;
 4 int f[501][501];
 5 //f[i][l]:以i作末尾,选了l本书时的最小花费
 6 struct info
 7 {
 8     int h, w;
 9 }a[1001];
10 bool cmp(const info & x, const info & y)
11 {
12     return x.h < y.h;
13 }
14 int main()
15 {
16     cin>>n>>k;
17     m=n-k;//选取m本书 
18     for(int i=1;i<=n;i++)
19         scanf("%d%d",&a[i].h,&a[i].w);
20 
21     sort(a+1,a+n+1,cmp);//高度决定顺序
22 
23     memset(f,20,sizeof(f));//初始极大,能缩小就缩小
24     for(int i=1;i<=n;i++)
25         f[i][1]=0;
26     //单独选择任何书都不会有花费
27     for(int i=2;i<=n;i++)
28         for(int l=2; l<=min(i,m);l++)//试着放第i本的时候 
29             for(int j=1;j<=i-1;j++)//尝试与前面第j本相邻
30             //放下第i本时,能从之前长1的队列继承为长2的队列,也能从之前长2的队列继承为长3的队列……l表示放下后的长度
31             //显然试到第i本时,长度不会超过i,也不会超过m,m是最终需要的长度
32                 if(j>=l-1)
33                     f[i][l]=min(f[i][l],f[j][l-1]+abs(a[i].w-a[j].w/*这是尝试相邻的书本*/));//放第i本继承到长度为l,总花费越小越好
34 
35     for(int i=m;i<=n;i++)
36         Min=min(Min,f[i][m]);//i的循环的意思是:以m结 尾的队列,可能最小,以m+1结尾的队列也可能的……以n结尾的队列也可能。
37 
38     printf("%d\n",Min);
39     return 0;
40 }
View Code

 

P1103 书本整理

标签:去掉   还需   排序   代码   names   print   决定   ace   ++   

原文地址:https://www.cnblogs.com/pangbi/p/12557898.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!