找出最优木棍序列(简单的递推。。。但是没做出来)

假设有一个木棍序列N,其长度分别为a1,a2,…aN。定义该序列的质量为

 F(N)= |a-b|+|b-c|+|c-d|

有个工厂老板找一批木棍,先后去了几个木材厂,都能够提供m个木棍。于是他就想从这么多木棍中找出一个木棍序列N,使得F(N)最小。但让他有个要求:

1  每个厂家只取一个木棍

每个厂家都有一个编号1-n,取木棍的顺序是按厂家编号进行。

输入:

包含多个测试用例,对每个测试用例,第一行包含两个整数n, m (1 <= n, m <= 1000)。 接下来的n行,每行包含m个数据,表示第n-1个厂家的m个木棍长度。处理到文件结束为止

输出:

对每个测试用例,在一行中输出F(N)的最小值 

样例输入:

3 3

2 3 1

4 7 6

7 9 2

样例输出

3

提示:满足条件的木棍序列式3 4 2。第一个厂家选3 第二个厂家选4 第三个厂家选2 

因为每行的取法只于上一列有关系!!!

那么可以一层一层的找。。。

但是为什么就错了呢???

题解用到了STL中的东西。。。

关于这个函数的具体用法:

函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置

举例如下:

一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标

pos = lower_bound( number, number + 8, 3) - number,pos = 0.即number数组的下标为0的位置。

pos = lower_bound( number, number + 8, 9) - number, pos = 1,即number数组的下标为1的位置(即10所在的位置)。

pos = lower_bound( number, number + 8, 111) - number, pos = 8,即number数组的下标为8的位置(但下标上限为7,所以返回最后一个元素的下一个元素)。

所以,要记住:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!~

返回查找元素的第一个可安插位置,也就是“元素值>=查找值”的第一个元素的位置

摘自:http://blog.csdn.net/niushuai666/article/details/6734403

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 #include<math.h>
 5 #include<iostream>
 6 #include<algorithm>
 7 using namespace std;
 8 #define inf 1<<30
 9 int n,m,cap[1010][1010];
10 int Min[1010][1010];
11 int main()
12 {
13     int i,j;
14     while(scanf("%d%d",&n,&m)!=EOF)
15     {
16           for(i=0;i<n;i++)
17           {
18               for(j=0;j<m;j++)
19               scanf("%d",&cap[i][j]);
20               sort(cap[i],cap[i]+m);
21           }
22           memset(Min,0,sizeof(Min));
23           for(i=1;i<n;i++)
24           {
25                 for(j=0;j<m;j++)
26                 {
27                       Min[i][j]=inf;
28                   int temp=lower_bound(cap[i-1],cap[i-1]+m,cap[i][j])-cap[i-1];
29                   if(temp<m)
30                      Min[i][j]=min(Min[i][j],Min[i-1][temp]+abs(cap[i-1][temp]-cap[i][j]));
31                     if(temp>0)
32                      Min[i][j]=min(Min[i][j],Min[i-1][temp-1]+abs(cap[i-1][temp-1]-cap[i][j]));
33               }
34             }
35             int ans=inf;
36             for(i=0;i<m;i++)
37              ans=min(ans,Min[n-1][i]);
38             printf("%d
",ans);
39     }
40     return 0;
41 }
原文地址:https://www.cnblogs.com/tt123/p/3305456.html