P1233 木棍加工【dp】

题目描述

一堆木头棍子共有n根,每根棍子的长度和宽度都是已知的。棍子可以被一台机器一个接一个地加工。机器处理一根棍子之前需要准备时间。准备时间是这样定义的:

第一根棍子的准备时间为1分钟;

如果刚处理完长度为L,宽度为W的棍子,那么如果下一个棍子长度为Li,宽度为Wi,并且满足L>=Li,W>=Wi,这个棍子就不需要准备时间,否则需要1分钟的准备时间;

计算处理完n根棍子所需要的最短准备时间。比如,你有5根棍子,长度和宽度分别为(4, 9),(5, 2),(2, 1),(3, 5),(1, 4),最短准备时间为2(按(4, 9)、(3, 5)、(1, 4)、(5, 2)、(2, 1)的次序进行加工)。

输入格式

第一行是一个整数n(n<=5000),第2行是2n个整数,分别是L1,W1,L2,w2,…,Ln,Wn。L和W的值均不超过10000,相邻两数之间用空格分开。

输出格式

仅一行,一个整数,所需要的最短准备时间。

输入输出样例

输入 #1
5
4 9 5 2 2 1 3 5 1 4
输出 #1
2

题解:
  和导弹拦截很像的一题,直接扣导弹拦截的板子就行。
  根据定理,LCS的个数等于LIS的长度
  以Li为第一关键字排序后,对Wi求一个LIS即可
 1 #include <bits/stdc++.h>
 2 #define dbug(x) cout << #x << "=" << x << endl
 3 #define eps 1e-8
 4 #define pi acos(-1.0)
 5  
 6 using namespace std;
 7 typedef long long LL;
 8  
 9 const int inf = 0x3f3f3f3f;
10  
11 template<class T>inline void read(T &res)
12 {
13    char c;T flag=1;
14    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
15    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
16 }
17 
18 const int maxn = 2e5 + 7;
19 
20 int n;
21 
22 struct node {
23     int l, r;
24     bool operator<(const node &t) const {
25         return l > t.l;
26     }
27 } a[maxn];
28 
29 int f1[maxn], f2[maxn];
30 int len1, len2;
31 
32 int main()
33 {
34     read(n);
35     for ( int i = 1; i <= n; ++i ) {
36         read(a[i].l); read(a[i].r);
37     }
38     sort(a + 1, a + n + 1);
39     // for ( int i = 1; i <= n; ++i ) {
40     //     printf("l:%d r:%d\n",a[i].l, a[i].r);
41     // }
42     len2 = 1;
43     f2[1] = a[1].r;
44     for (int i = 2; i <= n; ++i) {
45         if (f2[len2] < a[i].r) {
46             f2[++len2] = a[i].r;
47         } else {
48             int p = lower_bound(f2 + 1, f2 + len2 + 1, a[i].r) - f2;
49             f2[p] = a[i].r;
50         }
51     }
52     cout << len2 << endl;
53     return 0;
54 }

 


posted @ 2020-11-10 17:06  Orangeko  阅读(117)  评论(0编辑  收藏  举报