ZOJ 2283 Challenge of Wisdom 数论,Dilworth Theorem,求最长反链 难度:2
Challenge of Wisdom
Time Limit: 2 Seconds Memory Limit: 32768 KB
Background
"Then, I want to know whether you're a wise boy!"
Problem
"I have a great deal of lands. They're divided into N*M grids (N, M <= 1,000,000,000). When you are in (x, y), you may move into (x+1, y) or (x, y+1). I have P (P <= 100,000) treasures in the lands; each time, you can pick up anything you like."
"Now, I'll give you a map of my treasures; tell me, wise boy, how many times you need to pick up all the treasures?"
Input
This problem contains multiple test cases.
Each test case begins with 3 integers N, M and P. then followed by P lines, each lines contains 2 numbers: x, y, representing the location of a treasure.
Output
For each test case, output the minimum times I need.
Sample Input
7 7 7
1 2
1 4
2 4
2 6
4 4
4 7
6 6
Sample Output
2
Contest: A Great Beloved and My Gate to Freedom
There is a cx, there is a love_cx.
从左上角出发,对于
OO
OX
这种右方和下方同时存在的情况,无论是先去右方还是先去下方,都必然有一个是新开始点,+1次数,所以可以直接以x坐标为主,y坐标为辅排序,这个时候直接选定决策优先向右走即可,次数不会发生变化
但是直接模拟会超时,需要更普遍的规律,明显对于上图,有排序是(x,y),(x,y+1),(x+1,y)也就是说y会出现逆序,每出现一次逆序,有两种可能,第一种是这个逆序之前已经被拆分了(某个点已经被走过),另一种是需要多走一次,找到最长的逆序,这就是答案
下面是理论依据
________________________________________________________________________________
转载自 http://blog.csdn.net/xuzengqiang/article/details/7266034
偏序的概念:
设A是一个非空集,P是A上的一个关系,若关系P是自反的、反对称的、和传递的,则称P是集合A上的偏序关系。
即P适合下列条件:
(1)对任意的a∈A,(a,a)∈P;
(2)若(a,b)∈P且(b,a)∈P,则a=b;
(3)若(a,b)∈P,(b,c)∈P,则(a,c)∈P,则称P是A上的一个偏序关系。带偏序关系的集合A称为偏序集或半序集。
若P是A上的一个偏序关系,我们用a≤b来表示(a,b)∈P。
比方说:(A,≤)是偏序集,A={1,2,3},偏序≤在A上的大于等于关系。则有:≤={<3,3>,<3,2>,<3,1>,<2,2>,<2,1>,<1,1>},则有3≤2,2≤2,2≤1....
举如下例子说明偏序关系:
1、实数集上的小于等于关系是一个偏序关系。
2、设S是集合,P(S)是S的所有子集构成的集合,定义P(S)中两个元素A≤B当且仅当A是B的子集,即A包含于B,则P(S)在这个关系下成为偏序集。
3、设N是正整数集,定义m≤n当且仅当m能整除n,不难验证这是一个偏序关系。注意它不同于N上的自然序关系。
在Partially order set(偏序集)有一个非常NX的定理叫Dilworth Theorem。偏序集的定义是
偏序是在集合X上的二元关系≤(这只是个抽象符号,不是“小于或等于”),它满足自反性、反对称性和传递性。即,对于X中的任意元素a,b和c,有:
自反性:a≤a;
反对称性:如果a≤b且b≤a,则有a=b;
传递性:如果a≤b且b≤c,则a≤c 。
带有偏序关系的集合称为偏序集。
令(X,≤)是一个偏序集,对于集合中的两个元素a、b,如果有a≤b或者b≤a,则称a和b是可比的,否则a和b不可比。
例:(A,≤)是偏序集,其中A={1,2,3,4,5},其中≤是整除关系,那么对任意的x∈p都有1≤x,所以1和1,2,3,4,5都是可比的,但是2不能整除3,且3不能整除2,所以2和3是不可比的。
在X中,对于元素a,如果任意元素b,由b≤a得出b=a,则称a为极小元。
一个反链A是X的一个子集,它的任意两个元素都不能进行比较。
一个链C是X的一个子集,它的任意两个元素都可比。
下面是两个重要定理:
定理1 令(X,≤)是一个有限偏序集,并令r是其最大链的大小。则X可以被划分成r个但不能再少的反链。
其对偶定理称为Dilworth定理:
定理2 令(X,≤)是一个有限偏序集,并令m是反链的最大的大小。则X可以被划分成m个但不能再少的链。
证明:设p为最少反链个数
(1)先证明X不能划分成小于r个反链。由于r是最大链C的大小,C中任两个元素都可比,因此C中任两个元素都不能属于同一反链。所以p>=r。
(2)设X1=X,A1是X1中的极小元的集合。从X1中删除A1得到X2。注意到对于X2中任意元素a2,必存在X1中的元素a1,使得a1<=a2。令A2是X2中极小元的集合,从X2中删除A2得到X3……最终,会有一个Xk非空而X(k+1)为空。于是A1,A2,...,Ak就是X的反链的划分,同时存在链a1<=a2<=...<=ak,其中ai在Ai内。由于r是最长链大小,因此r>=k。由于X被划分成了k个反链,因此r>=k>=p。因此r=p,定理1得证。
搞清楚了反链和链的定义,就能够很好的从Hasse Diagram中得到理解。链就是从纵向的角度看 Hasse Diagram ,反链是从横向的角度看Hasse Diagram。
定理一,就是至少有r行构成反链关系。
定理二,就是至少有m列构成链关系。
___________________________________________________
如何找到最长反链?
偏序关系是小于等于,反链肯定满足严格递减,也就是大于关系,但是这个反链是位置不连续的,不能直接简单靠dp求,可以先从前面出发,把递增数列保存在数组中,如果新值小于这个数列最小值,那么就放在最末尾,也就是递增数列的长度增加,否则,二分找到可以放置的位置,这个位置上的数字小于新值,替换之,以使这个数列更优,依然能保证更新时较小的值位置后于较大的值
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1e6+5;
int n,m,p;
struct pnt{
int x,y;
pnt(){x=y=0;}
pnt(int x,int y){this->x=x;this->y=y;}
bool operator < (pnt p2)const {return x!=p2.x?x<p2.x:y<p2.y;}
bool operator > (pnt p2)const {return x!=p2.x?x>p2.x:y>p2.y;}
pnt operator = (const pnt p2){x=p2.x;y=p2.y;return *this;} };
pnt pt[maxn];
int dp[maxn],len; void replace(int x){
int l=0,r=len;
while(r>l){
int m=(l+r)>>1;
if(dp[m]>x){
l=m+1;
}
else {
r=m;
}
}
if(dp[l]<x&&l<len)dp[l]=x;
} int main(){
while(scanf("%d%d%d",&n,&m,&p)==3){
len=0; for(int i=0;i<p;i++){
scanf("%d%d",&pt[i].x,&pt[i].y);
}
sort(pt,pt+p); if(p>0)dp[len++]=pt[0].y;
for(int i=1;i<p;i++){
if(dp[len-1]>pt[i].y){
dp[len++]=pt[i].y;
}
else {
replace(pt[i].y);
}
}
printf("%d\n",len);
}
return 0;
}
ZOJ 2283 Challenge of Wisdom 数论,Dilworth Theorem,求最长反链 难度:2的更多相关文章
- ZOJ 2283 Challenge of Wisdom
题意:在一个n * m的地图里,有p个宝藏,每次只能向横纵坐标增加的方向走,问最少走几次能把宝藏都拿走. 解法:按横坐标排序,纵坐标的一个不下降子序列就是一条合法路径,要求多少条不下降子序列可以覆盖所 ...
- ZOJ 1542 POJ 1861 Network 网络 最小生成树,求最长边,Kruskal算法
题目连接:problemId=542" target="_blank">ZOJ 1542 POJ 1861 Network 网络 Network Time Limi ...
- pat l2-14 列车调度 dilworth+nlog(n)最长上升子序列
关于dilworth定理 这里引用一个大神的(http://blog.csdn.net/xuzengqiang/article/details/7266034) 偏序的概念: 设A是一个非空集,P是A ...
- zoj 3795 Grouping tarjan缩点 + DGA上的最长路
Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Submit Status Practic ...
- [zoj 3774]Power of Fibonacci 数论(二次剩余 拓展欧几里得 等比数列求和)
Power of Fibonacci Time Limit: 5 Seconds Memory Limit: 65536 KB In mathematics, Fibonacci numbe ...
- ZOJ 3707 Calculate Prime S 数论
思路:容易得到s[n]=s[n-1]+s[n-2],也就是fib数. 求第k小的fib质数的也就是第k个质数数-2,当k>2时. 在就是s[n]/x%m=s[n]%(x*m)/x. 代码如下: ...
- zoj 1610 Count the Colors 【区间覆盖 求染色段】
Count the Colors Time Limit: 2 Seconds Memory Limit: 65536 KB Painting some colored segments on ...
- POJ 1201 & HDU1384 & ZOJ 1508 Intervals(差分约束+spfa 求最长路径)
题目链接: POJ:http://poj.org/problem?id=1201 HDU:http://acm.hdu.edu.cn/showproblem.php? pid=1384 ZOJ:htt ...
- ZOJ 2588 Burning Bridges(无向连通图求割边)
题目地址:ZOJ 2588 由于数组开小了而TLE了..这题就是一个求无向连通图最小割边.仅仅要推断dfn[u]是否<low[v],由于low指的当前所能回到的祖先的最小标号,增加low[v]大 ...
随机推荐
- dev-server.js详解
转载自:https://www.cnblogs.com/ye-hcj/p/7091706.html dev-server.js详解 require('./check-versions')() var ...
- linux 自启动方法
参考文章:http://vod.sjtu.edu.cn/help/Article_Print.asp?ArticleID=626 http://hiandroidstudio.blog.51cto.c ...
- NetBeans 启动时出现 Invalid jdkhome specified提示
执行 NetBeans 出现如下文字内容: Invalid jdkhome specifiedCannot locate java installation in specifired jdkhome ...
- sqlite常用的命令-增删改查
一.查看版本信息: #sqlite3 -version 二.sqlite3常用命令 1.当前目录下建立或打开test.db数据库文件,并进入sqlite命令终端,以sqlite>前缀标识: 2. ...
- genisoimage命令用法
功能说明:建立ISO 9660映像文件. 常用命令:genisoimage -o imagename.iso file 语 法:mkisofs [-adDfhJlLNrRTvz][-print-si ...
- live555笔记_hi3516A
1.简介 是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输协议如RTP/RTCP.RTSP.SI ...
- RabbitMQ学习之(一)_初步了解RabbitMQ、RabbitMQ的使用流程、为什么要使用RabbitMQ、RabbitMQ的应用场景
初识RabbitMQ RabbitMQ是一个在AMQP协议基础上实现的消息队列系统, 是一个消息代理.它的核心原理非常简单:接收和发送消息.你可以把它想像成一个邮局:你把信件放入邮箱,邮递员就会把信件 ...
- 20145321 《Java程序设计》第10周学习总结
20145321 <Java程序设计>第10周学习总结 教材学习内容总结 网络编程:网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输. IP地址:为了能够方便的识别网络上 ...
- C++ 程序崩溃时生成Dump文件
#include <DbgHelp.h> //生产DUMP文件 int GenerateMiniDump(HANDLE hFile, PEXCEPTION_POINTERS pExcept ...
- springmvc.xml配置图解