洛谷 P1233 木棍加工

洛谷传送门

思路

遇到这种有两个维度的问题,考虑先按其中一个维度排序。在本题中将所有木棍按照 Li 从大到小排序,则排序后一定是从左往右选。

排序后问题就变成了:

有长为 n 的数组 W1,W2,...,Wn,每次可选出该数组的一个子序列 a1,a2,..,ak 满足 a1a2...ak 并删去,求至少要删几次才能把整个数组删空。

可以利用 Dilworth 定理将问题转化为求 Wi 的 LIS。

Dilworth 定理:对于任意有限偏序集,其最大反链中元素的数目必等于最小链划分中链的数目。

于是这题就做完了。

code
/*
p_b_p_b txdy
AThousandMoon txdy
AThousandSuns txdy
hxy txdy
*/
#include <bits/stdc++.h>
#define pb push_back
#define fst first
#define scd second
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
const int maxn = 5050;
int n, f[maxn];
struct node {
int a, b;
} a[maxn];
bool cmp(node a, node b) {
return a.a > b.a || (a.a == b.a && a.b > b.b);
}
void solve() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &a[i].a, &a[i].b);
}
sort(a + 1, a + n + 1, cmp);
int ans = 0;
for (int i = 1; i <= n; ++i) {
f[i] = 1;
for (int j = 1; j < i; ++j) {
if (a[j].b < a[i].b) {
f[i] = max(f[i], f[j] + 1);
}
}
ans = max(ans, f[i]);
}
printf("%d\n", ans);
}
int main() {
int T = 1;
// scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}
posted @   zltzlt  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示