分析:这题就是渡轮问题的改动版,还是用最长上升子序列来做,不过B序列中的一个点不止对应一个A序列中的一个点,而是最多6个点,那么我们就可以把B串中的每一个点用与之对应的A串中的6个点替换,并且按从大到小的顺序替换,用来保证每次只会在这6个点中选出一个点。
AC代码:
/*************************************************************************
> File Name: B.cpp
> Author: Akira
> Mail: qaq.febr2.qaq@gmail.com
> Created Time: 2017年03月04日 星期六 21时01分46秒
************************************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<cmath>
#include<vector>
#include<set>
#include<list>
#include<ctime>
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
#define MST(a,b) memset(a,b,sizeof(a))
#define CLR(a) MST(a,0)
#define Sqr(a) ((a)*(a))
using namespace std;
#define MaxN 100001
#define MaxM MaxN*10
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
const int mod = 1e9+7;
const int eps = 1e-8;
#define bug cout << 88888888 << endl;
int n;
int DP[MaxN*10];
int arr[MaxN*10];
int LIS()
{
CLR(DP);
int top = 0;
DP[0] = -1;
for(int i=0;i<n*6;i++)
{
if(arr[i]>DP[top]) DP[++top] = arr[i];
else
{
int low = 1, high = top;
while(low<=high)
{
int mid = (low+high)/2;
if(arr[i]>DP[mid]) low = mid+1;
else high = mid-1;
}
DP[low] = arr[i];
}
//cout << top << " " << DP[top] << endl;
}
return top;
}
void solve()
{
printf("%d\n", LIS());
}
int main()
{
while(~scanf("%d", &n))
{
for(int i=0;i<n;i++)
{
int matching[6];
for(int j=0;j<6;j++)
{
scanf("%d", &matching[j]);
}
sort(matching,matching+6);
for(int j=0;j<6;j++)
{
arr[i*6+5-j] = matching[j];
}
}
solve();
}
}