HDU 1051 Wooden Sticks

Description

There is a pile of wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to prepare processing a stick. The setup times are associated with cleaning operations and changing tools and shapes in the machine. The setup times of the woodworking machine are given as follows:
  • The setup time for the first wooden stick is 1 minute.
  • Right after processing a stick of length and weight , the machine will need no setup time for a stick of length l' and weight w' if l<=l' and <=w' .
Otherwise, it will need 1 minute for setup.
You are to find the minimum setup time to process a given pile of wooden sticks. For example, if you have five sticks whose pairs of length and weight are (4,9), (5,2), (2,1), (3,5), and (1,4) then the minimum setup time should be 2 minutes since there is a sequence of pairs (1,4), (3,5), (4,9), (2,1), (5,2).

Input 

The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line has an integer n, 1<=n<=5000, that represents the number of wooden sticks in the test case, and the second line contains 2positive integers l1w1l2w2, ..., lnwn, each of magnitude at most 10000, where li and wi are the length and weight of the th wooden stick, respectively. The 2integers are delimited by one or more spaces.

Output 

The output should contain the minimum setup time in minutes, one per line.

Sample Input 

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

Sample Output 

2
1
3


题目的意思
木棒有长度l和重量w两个属性。
给定一些木棒,设木棒s'排在木棒s后面,若 l <=l' and w <=w' 则setup time不用作任何处理,否则+1
不同的排序有不同的setup time,要求输出最小的setup time
实质就是求最小有几个递增序列

思路:
对所有木棒先按照l递增排序,若l一样再按照w递增排序。
如(1,3) (2,4) (3,1) (3,2) (4,3) (5,5)
此时我们可以看到,l的排序已经符合要求,现在求的就是所有的w组成的序列中最少有几个递增序列。
(其实没有所谓的最少,因为按照这样排序后递增序列的数目已经确定了)
所以现在题目转化为【给定序列,求递增子序列的个数】
类似拦截导弹 http://acm.nyist.net/JudgeOnline/problem.php?pid=79

初始化dis[]数组记录子序列个数。
遍历序列中每个元素i,i依次和它前面的元素j比较。
若wi大于前面的元素的wj,说明此时包含j在内的序列的递增性质被破坏了,
更新dis[i]:dis[j]+1(dis[i]表示i属于第几个递增子序列),所以若i破坏了j的递增性质,则i应当属于第dis[j]+1个递增序列。
如(1,3) (2,4) (3,1) (3,2) (4,3) (5,5)
遍历完毕后dis[] = {1,1,2,2,2,1}
此时输出dis[]最大那个就是答案啦~

View Code
#include<iostream>
#include<algorithm>
using namespace std;
struct Node
{
    int l,w;
};

bool cmp(Node a, Node b)
{
    if (a.l == b.l)
        return a.w < b.w;
    
    return a.l < b.l;
}

int main()
{
    int m;
    
    cin >> m;
    
    while (m--)
    {
        int n;
        
        cin >> n;
        
        Node s[n];
        
        int dis[n];
        
        for (int i = 0; i < n; ++i)
        {
            cin >> s[i].l >> s[i].w;
        }
        
        sort(s, s+n, cmp);
        
        for (int i = 0; i < n; ++i)
            dis[i] = 1;
            
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < i; ++j)
            {
                if (s[i].w < s[j].w && dis[i] < dis[j]+1)
                    dis[i] = dis[j]+1;
            }
        }
        
        cout << *max_element(dis, dis+n) << endl;
    }
}
原文地址:https://www.cnblogs.com/chenyg32/p/3073386.html