# NENUOJ 之 算法2贪心F

# F001 木棒加工问题 (opens new window)

# 题目描述

现有n根木棒,已知它们的长度和重量。要用一部木工机一根一根地加工这些木棒。该机器在加工过程中需要一定的准备时间,是用于清洗机器,调整工具和模板的。木工机需要的准备时间如下: (1) 第一根木棒需要1min的准备时间; (2) 在加工了一根长为l,重为w的木棒之后,接着加工一根长为l’(l≤l’),重为w’(w≤w’)的木棒是不需要任何准备时间的。否则需要一分钟的准备时间。 给定n根木棒,你要找到最少的准备时间。例如现在有长和重分别为(4,9),(5,2),(2,1),(3,5)和(1,4)的五根木棒,那么所需准备时间最少为2min,顺序为(1,4),(3,5),(4,9),(2,1),(5,2)。

# 输入

输入有多组测试例。输入数据的第一行是测试例的个数(T)。每个测试例两行:第一行是一个整数n(1≤n≤5000),表示有多少根木棒;第二行包括n*2个整数,表示l1,w1,l2,w2,l3,w3,…,ln,wn,全部不大于10000,其中li和wi表示第i根木棒的长度和重量。数据由一个或多个空格分隔。

# 输出

输出是以分钟为单位的最少准备时间,一行一个。

# 样例输入 复制

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

代码C++:

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e4 + 7;

struct stick {
    int l, w;
} s[MAXN];

int vis[MAXN];

bool cmp(struct stick a,struct stick b) {
    if (a.l == b.l) return a.w < b.w; // 长度相同时按重量升序排序
    return a.l < b.l; // 按长度升序排序
}

void solve() {
    int n, ans = 0;
    cin >> n;
    memset(vis, 0, sizeof(vis));
    for (int i = 1; i <= n; i++) {
        cin >> s[i].l >> s[i].w;
    }
    sort(s + 1, s + n + 1, cmp);

    for (int i = 1; i <= n; i++) {
        if (vis[i]) continue; // 已经使用过的木棒跳过
        ans++;
        int cur_l = s[i].l, cur_w = s[i].w;
        vis[i] = 1; // 标记当前木棒为已用
        for (int j = i + 1; j <= n; j++) {
            if (!vis[j] && s[j].l >= cur_l && s[j].w >= cur_w) {
                cur_l = s[j].l; // 更新当前长度
                cur_w = s[j].w; // 更新当前重量
                vis[j] = 1; // 标记为已用
            }
        }
    }
    cout << ans << "\n";
}

int main() {
    int t;
    cin >> t;
    while (t--) solve();
    return 0;
}