您的位置:首页 > 其它

POJ1065 动态规划 LIS

2018-03-16 00:35 190 查看
题意:

求偏序集链的最小划分数。

思路:

1、贪心;

2、利用Dilworth定理转化成LIS模型。

反思:

Dilworth定理:偏序集中链的最小划分数 = 最长反链长度。

同HDU1257 导弹拦截系统

代码:

1、贪心

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 5000 + 10;
const int INF = 0x3f3f3f3f;
struct S
{
int l, w;
}arr[MAXN];
bool cmp(S b, S a)
{
return b.l == a.l ? b.w <= a.w : b.l < a.l;
}
bool vis[MAXN];
int main()
{
int t; scanf("%d", &t);
while(t--)
{
memset(vis, false, sizeof(vis));

int n; scanf("%d", &n);
for(int i = 0; i < n; i++)
{
int l, w;
scanf("%d%d", &arr[i].l, &arr[i].w);
}

sort(arr, arr + n, cmp);

int cnt = 1;
int ans = 1;
int nl = arr[0].l, nw = arr[0].w;
int head = 0;
vis[0] = true;
while(cnt < n)
{
for(int i = head + 1; i < n; i++)
{
if(arr[i].l >= nl && arr[i].w >= nw && !vis[i])
{
vis[i] = true;
cnt++;
nl = arr[i].l;
nw = arr[i].w;
}
}
if(cnt == n) break;
for(int i = 0; i < n; i++)
{
if(!vis[i])
{
head = i;
vis[i] = true;
cnt++;
break;
}
}
if(!(arr[head].l >= nl && arr[head].w >= nw))
{
ans++;
}
nl = arr[head].l;
nw = arr[head].w;
}
printf("%d\n", ans);
}
return 0;
}


2、LIS

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 5000 + 10;
const int INF = 0x3f3f3f3f;
struct S
{
int l, w;
}arr[MAXN];
bool cmp(S b, S a)
{
return b.l == a.l ? b.w <= a.w : b.l < a.l;
}
int dp[MAXN];
int main()
{
int t; scanf("%d", &t);
while(t--)
{
int n; scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%d%d", &arr[i].l, &arr[i].w);
}

sort(arr, arr + n, cmp);

for(int i = 0; i < n; i++)
{
dp[i] = 1;
for(int j = 0; j < i; j++)
{
if(arr[j].w > arr[i].w) dp[i] = max(dp[i], dp[j] + 1);
}
}
int ans = -INF;
for(int i = 0; i < n; i++)
{
ans = max(ans, dp[i]);
}
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: