您的位置:首页 > 其它

ZOJ 1025 Wooden Sticks 【思维 + 最长下降子序列 + Dilworth定理】

2018-03-30 12:10 525 查看
传送门

// 题意: 有n个木头, 每个木头有一个长度和重量. 每次一根木头准备需要1分钟, 如果下一根木头的(l’, w’) l’ >= l, w’ >= w, 那么就不用多余准备时间, 否则准备时间加1, 问处理掉这些木头最少需要多少分钟.

思路: 有一个很明显的二维偏序关系在里面, 那么假设我们只看一维, 那么就是问最少可以划分多少组最长不下降子序列, 那么由这个Dilworth定理我们可以转化为求这个序列的最长下降子序列, 所以我们对给定的长度和重量进行排序, 长度小的在前面, 否则重量小的在前面, 所以我们分别求这两个的最长下降子序列, 取max就是ans, 因为如果我们固定了一个量所求的答案只是单纯的对于某一个量而言的,而此时我们需要确定下另一个量是否也满足这个条件? 如果不满足就要取大的就一定同时满足两个量的条件了!!!

AC Code

const int maxn = 5e3+5;
int n, g[maxn];
int Bsearch(int x) {
int l = 1, r = n, mid, ans;
while(l <= r) {
mid = (l + r) >> 1;
if (g[mid] <= x) { // 严格小于
r = mid - 1;
ans = mid;
}
else l = mid + 1;
}
return ans;
}
struct node {
int x, y;
bool operator < (const node & _) const {
if (x == _.x) return y < _.y;
return x < _.x;
}
}e[maxn];
int cal(int f) {
Fill(g, -inf);
int ans = 0;
for (int i = 1 ; i <= n ; i ++) {
int tmp;
if (f) tmp = e[i].y;
else tmp = e[i].x;
int pos = Bsearch(tmp);
g[pos] = tmp;
ans = max(ans, pos);
}
return ans;
}
void solve()
{
scanf("%d", &n);
for (int i = 1 ; i <= n ; i ++) {
scanf("%d%d", &e[i].x, &e[i].y);
}
sort(e+1, e+1+n);
printf("%d\n", max(cal(0), cal(1)));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: