心急的C小加

第一部分:题目

心急的C小加  题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=236

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
 
描述

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
                                                                                           第二部分:思路
这题贪心的角度就是:尽量一次能够连续处理最多的木棒。那么这些木棒必须满足条件:后面的木棒的长度和重量必须大于等于前一个。怎么样能够得到最大值呢?先对长度或者重量进行从大到小排序,那么再看另一个数值是否满足条件即可。可是这题必须是先对长度进行排序,然后看重量(这就是这题的问题所在)。就相当于把这些木棒进行分组,每组按照长度从小到大排序,重量必须是非减序列。
处理的过程就是:小的先进行处理,后面只要是满足重量不小于前一个木棒就可以继续处理。也就是按照长度从小到大排序后,重量有多少个增序列?需要注意的是:在对长度进行排序时,如果长度相等,进一步对重量进行大小排序。因为数据量原因,排序使用快排。有需要的百度吧。
                                                                                           第三部分:代码
#include<stdio.h>
int fun(int v[100][2], int left, int right)//快速排序 
{
    if(left < right)
    {
        int key = v[left][0];
        int key2= v[left][1];
        int low = left;
        int high = right;
        while(low < high)
        {
            while(low < high && v[high][0] >= key)
            {
                if(v[high][0]==key&&v[high][1]<key2)//在长度相同的情况下再对重量进行排序 
                {
                    int t=v[high][1];
                    v[high][1]=key2;
                    key2=t;
                    v[low][1]=t;
                }
                high--;
            }
            v[low][0]= v[high][0];
            v[low][1]= v[high][1];
            while(low < high && v[low][0]<= key)
            {
                
                if(v[low][0]==key&&v[low][1]>key2)
                {
                    int t=v[low][1];
                    v[low][1]=key2;
                    key2=t;
                    v[high][1]= key2;
                }
                low++;
            }
            v[high][0]= v[low][0];
            v[high][1]= v[low][1];
        }
        v[low][0]= key;
        v[low][1]= key2;
    //注意:递归条件
        if(low-1>left)
        {
            fun(v,left,low-1);
        }
        if(low+1<right)
        {
            fun(v,low+1,right);
        }
    }
}
int main()
{
    int n,m,i,len;
    int s[5001][2];
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&len);
        for(i=1;i<=len;i++)
        {
            scanf("%d %d",&s[i][1],&s[i][0]);//存储木棒的长和重量 
        }
        fun(s,1,len);
        int count=0;//记录排序后的重量的增序列个数 
        for(i=1;i<=len;i++)
        {
            if(s[i][1]==0)//如果一个数在一个增序列中用过了就置为0
            {
                continue;
            }
            int j;
            count++;
            int temp=s[i][1];
            s[i][1]=0;
            for(j=i+1;j<=len;j++)
            {
                if(s[j][1]>=temp)
                {
                    temp=s[j][1];
                    s[j][1]=0;
                }
            }
        }
        printf("%d\n",count);
    }
    return 0;
}

 

posted @ 2016-04-18 23:33  喝醉的香锅锅  阅读(287)  评论(0编辑  收藏  举报