team2012-F3-sol-0012
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
题意:有两组选手,每组n个人,并且给定n个可以胜利的对决,且双方必须按顺序出场,求最多能胜利多少场。
解法:这是一个最长单调子序列问题,由n的范围需要用nlogn的解法,设minend[i]为长度为i的单调子序列的最小结尾,则minend递增,二分查找并更新即可
}}}
{{{
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 100004;
int n, len, minend[MAXN], f[MAXN];
int main()
{
while(cin>>n)
{
for(int i=1;i<=n;i++)
{
int a, b;
cin>>a>>b;
f[a] = b;
}
len = 0;
minend[0] = 0;
for(int i=1;i<=n;i++)
{
minend[i] = MAXN;
int loc = upper_bound(minend, minend+len+1, f[i]) - minend;
if(loc == len+1)
len++;
if(minend[loc] > f[i])
minend[loc] = f[i];
}
if(len*2 >= n)
cout<<len<<endl;
else
cout<<-1<<endl;
}
return 0;
}
}}}
题意:有两组选手,每组n个人,并且给定n个可以胜利的对决,且双方必须按顺序出场,求最多能胜利多少场。
解法:这是一个最长单调子序列问题,由n的范围需要用nlogn的解法,设minend[i]为长度为i的单调子序列的最小结尾,则minend递增,二分查找并更新即可
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 100004;
int n, len, minend[MAXN], f[MAXN];
int main()
{
while(cin>>n)
{
for(int i=1;i<=n;i++)
{
int a, b;
cin>>a>>b;
f[a] = b;
}
len = 0;
minend[0] = 0;
for(int i=1;i<=n;i++)
{
minend[i] = MAXN;
int loc = upper_bound(minend, minend+len+1, f[i]) - minend;
if(loc == len+1)
len++;
if(minend[loc] > f[i])
minend[loc] = f[i];
}
if(len*2 >= n)
cout<<len<<endl;
else
cout<<-1<<endl;
}
return 0;
}