1. 程式人生 > >偏序集,Dilworth定理,以及經典的導彈攔截問題

偏序集,Dilworth定理,以及經典的導彈攔截問題

偏序集:

設R為非空集合A上的關係,如果R是自反的、反對稱的和可傳遞的,則稱R為A上的偏序關係,簡稱偏序,通常記作≦。一個集合A與A上的偏序關係R一起叫作偏序集,記作<A,R>或<A, ≦>。其中(自反性)對任一,則x≦x;(反對稱性)如果x≦y,且y≦x,則x=y;(傳遞性)如果x≦y,且y≦c ,則x≦c。

(1)自反性:a≤a,∀a∈P;

(2)反對稱性:∀a,b∈P,若a≤b且b≤a,則a=b;

(3)傳遞性:∀a,b,c∈P,若a≤b且b≤c,則a≤c;

Dilworth定理:     偏序集能劃分成的最少的全序集的個數與最大反鏈的元素個數相等。

Dilworth定理的對偶定理:對於一個偏序集,其最少反鏈劃分數等於其最長鏈的長度。

對於導彈攔截問題:

也就是說把一個數列劃分成最少的最長上升子序列的數目就等於這個數列的最長下降子序列的長度

#include<iostream>
using namespace std;
#include<math.h>
#include<algorithm>
int a[100005];
int dp[100005];
int dp2[100005];
int ans=-1;
int ans1=-1;
int main()
{
	int num;
	int t=0;
	while(cin>>num)
	{
		if(cin.eof())break;
		a[t]=num;
		dp[t]=1;
		dp2[t]=1;
		t++;
	}
	for(int i=0;i<t;i++)		//從i開始取 
	{
		for(int j=0;j<i;j++)	//
		{
			if(a[j]>=a[i])
			{
				dp[i]=max(dp[i],dp[j]+1);
			}
			if(a[j]<=a[i])
			{
				dp2[i]=max(dp2[i],dp2[j]+1);
			}
		}
		ans=max(ans,dp[i]);
		ans1=max(ans1,dp2[i]);
	}
	cout<<ans<<endl;
	cout<<ans1<<endl;
	return 0;
}