1. 程式人生 > >【 OJ 】 HDOJ1051 18年12月19日21:14 [ 45 ]

【 OJ 】 HDOJ1051 18年12月19日21:14 [ 45 ]

思路模擬,利用l排序,先確定l小的在前,如果相等再排序w,由於是基本有序的狀態,所以只要比較後面的是否w大於前面的即可

利用visit記錄訪問,從第一個開始訪問,將後面能串起來的都串起來(符合l'>l w'>w都標記已訪問),直到所有都被訪問,這時候記錄串了幾次就可。

#include<iostream>
# include<algorithm>
using namespace std;
struct nn {
	int l, w;
}a[5000];//最大5000
bool cmp(nn a, nn  b) {
	return a.l == b.l ? a.w < b.w : a.l < b.l;
}
bool visit[5000];
int main(void) {
	int T, n;
	cin >> T;
	while (T--) {
		cin >> n;//先l 後 w
		memset(visit, 0, sizeof(bool)*n);//初始化dp
		for (int i = 0; i < n; i++) {
			cin >> a[i].l >> a[i].w;
		}//錄入資料
		sort(a, a + n, cmp);//排序
		int res=0;
		for (int i = 0; i < n; i++) {
			if (!visit[i]) {
				visit[i] = 1;
				res++;
				int cur = i;
				for (int k = i + 1; k < n; k++) {
					if (!visit[k]&&a[k].w >= a[cur].w) {//(1,4), (3,5), (4,9)    (2,1), (5,2).
						visit[k] = 1; cur = k;
					}
				}
			}
		}
		cout << res << endl;
	}
	system("pause");
	return 0;
}

LIS 動態規劃做法:

#include<iostream>
# include<algorithm>
using namespace std;
struct nn {
	int l, w;
}a[5000];//最大5000
bool cmp_( nn a, nn  b) {
	return a.l == b.l ? a.w < b.w : a.l < b.l;
}
int dp[5000];
int main(void) {
	int T,n;
	cin >> T;
	while (T--) {
		cin >> n;//先l 後 w
		memset(dp, 0, sizeof(int)*n);//初始化dp
		for (int i = 0; i < n; i++) {
			cin >> a[i].l >> a[i].w;
			dp[i] = 1;
		}//錄入資料
		sort(a, a + n,cmp_);//排序
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < i; j++)
				if (a[i].w < a[j].w&&dp[i] < dp[j]+1) {
					dp[i] = dp[j] + 1;
				}
		}
		cout << *max_element(dp, dp + n)<<endl;
	}
	system("pause");
	return 0;
}