心急的c小加

来源:互联网 发布:拓扑布局算法 编辑:程序博客网 时间:2024/06/10 05:05

心急的C小加

描述

C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的时间,如果第i+1个木棒的重量和长度都大于等于第i个处理的木棒,那么将不会耗费时间,否则需要消耗一个单位的时间。因为急着去约会,C小加想在最短的时间内把木棒处理完,你能告诉他应该怎样做吗?

输入

第一行是一个整数T(1<T<1500),表示输入数据一共有T组。
每组测试数据的第一行是一个整数N(1<=N<=5000),表示有N个木棒。接下来的一行分别输入N个木棒的L,W(0 < L ,W <= 10000),用一个空格隔开,分别表示木棒的长度和质量。

输出

处理这些木棒的最短时间。

样例输入

3

5

4 9 5 2 2 1 3 5 1 4

3

2 2 1 1 2 2

3

1 3 2 2 3 1

样例输出

2

1

3

思路:先排序,然后把每次长度和质量递增的木块标记为1,然后依次筛选,用sum计数

#include<iostream>

#include<stdio.h>

#include<algorithm>

using namespace std;

struct book{

int a;

int b;

}s[5010],k;

bool cmp(book x,book y)

{

if(x.a==y.a)

return x.b<y.b;

else

return x.a<y.a;

}

int main()

{

int m,n,i,j,sum;

int h[5010];

cin>>m;

while(m--)

{

sum=0;

cin>>n;

for(i=0;i<n;i++)

{

cin>>s[i].a>>s[i].b;

h[i]=0;

}

sort(s,s+n,cmp);

for(i=0;i<n;i++)

{

if(h[i]==0)

{

sum++;

h[i]=1;

k=s[i];

for(j=i+1;j<n;j++)

{

if(k.b<=s[j].b&&h[j]==0)

{

k=s[j];

h[j]=1;

}

}

}

}

cout<<sum<<endl;

}

return 0;

}

详解思路:

1)首先对输入的所有木棒按长度和重量进行从小到大的排序(先排长度,长度相同再排重量)

2)获得一个有序的序列之后,再从这个序列中找出有多少个子序列,就表示需要处理多少次,要花多少个单位时间了

3)比如: 输入是

4 9 5 2 2 1 3 5 1 4

这一组共有5个,排完序应是这样的(1 4)(2 1)(3 5) (4 9) (5 2)

再从这个5个里面找出子序列,步骤如下:

a. (1 4)是第一个,需要花一个单位时间处理,(1 4)是一个子序列 , 我们叫它序列1

b. (2 1)进来,在他前面没有比他小的(长度和重量都小),如是(2 1)也是一个子序列,我们叫它序列2

c. (3 5)进来,它比前面的(1 4) 和(2 1)都大,随便选一个(默认是第一个),于是把它放到序列1, 这时候序列1是(1 4) (3 5)

除此之外还要用(3 5)替代(1 4)来跟后面的比较,因为只要后面的比(3 5)大那它肯定也比(1 4)大【例(4 6)】,但如果它不比(3 5)大但比(1 4)大 【例4 4)】就可以看作序列1是(1 4) (4 4),然后(3 5) 单独做序列3。其效果是一样的,只不过序列1的内容不同

d. (4 9)进来,它比前面的 (3 5) 大,如果把它放到序列1,这时候序列1 是 (1 4) (3 5) (4 9),同时 (4 9)替代(3 5)跟后面的比较

e. (5 2)进来,它比前面的(4 9)小,但比(2 1)大,如是把它放到序列2,这时候序列2 是 (2 1) (5 2),并用(4 2)替代(2 1)跟后面的比较

综上所述,最后一共有2个子序列 :

1 4) (3 5) (4 9) 和 (2 1) (5 2)

比较序列就是这2个子序列各自的最后一个元素( 4 9) 和 (5 2)

所以处理时间一共就是2.

0 0