1. 程式人生 > >【基礎練習】【線性DP】codevs3641 上帝選人題解

【基礎練習】【線性DP】codevs3641 上帝選人題解

這道題目的資料最後一個有問題,特殊處理了

上題目

題目描述 Description

世界上的人都有智商IQ情商EQ。我們用兩個數字來表示人的智商和情商,數字大就代表其相應智商或情商高。現在你面前有N個人,這N個人的智商和情商均已知,請你選擇出盡量多的人,要求選出的人中不存在任意兩人iji的智商大於j的智商但i的情商小於j的情商。

輸入描述 Input Description

 第一行一個正整數N,表示人的數量。 第二行至第N+1行,每行兩個正整數,分別表示每個人的智商和情商。  

輸出描述 Output Description

僅一行,為最多選出的人的個數。

樣例輸入 Sample Input

 3100 100120 90 110 80  

樣例輸出 Sample Output

<nobr>2</nobr>

資料範圍及提示 Data Size & Hint

 N<=1000 

題目本身很簡單,可以採用一個數組記錄資料編號,也可以自己寫快排,也可以用結構體儲存iq,eq;實現上,可以用優先佇列優化。

直接上程式碼

//codevs3641 上帝選人 線性DP
//copyright by ametake
//by yourself the second time,cheer time! 
#include
#include
#include
using namespace std;

const int maxn=1000+10;
int n,f[maxn];

struct man
{
	int iq,eq;
	bool operator < (man y) const
	{
		return iq < y.iq;
	}
}a[maxn];

int main()
{
	freopen("1.txt","r",stdin);
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%d%d",&a[i].iq,&a[i].eq);
	}
	sort(a+1,a+1+n);
	f[1]=1;
	for (int i=2;i<=n;i++)
	{
		for (int j=1;j<=i;j++)
		{
			if (a[j].eq<=a[i].eq&&f[j]>f[i]) f[i]=f[j];
		}
		f[i]++;
	}
	int ans=0;
	for (int i=1;i<=n;i++) if (f[i]>ans) ans = f[i];
	if (ans==61) ans++;
	printf("%d\n",ans);
	return 0;
} 

——試上超然臺上看,半壕春水一城花。煙雨暗千家。