题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=1288
标记一下LIS的DP解法:其中len[i]代表以array[i]结尾的单调递增字串的最大值。(标记一下,有些不对,以后再改)
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
int array[40003];
int len[40003];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int t;
int n;
scanf("%d",&t);
while(t--)
{
scanf(" %d",&n);
memset(array,0,sizeof(array));
for(int i=1; i<=n; i++)
{
scanf(" %d",&array[i]);
}
for(int i=0; i<=n;i++)
{
len[i] = 1;
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<i; j++)
{
if(array[j]<array[i])
{
len[i] = max(len[i],len[j] + 1);
}
}
}
int max = 0;
for(int i=1;i<=n;i++)
{
if(len[i]>max)
{
max = len[i];
}
}
printf("%d\n",max);
}
return 0;
}
时间复杂度O(n^2),40000数据会超时。
用以前二分法的O(nlogn)来做, 具体参看模板:http://blog.youkuaiyun.com/niuox/article/details/7706382
二分法:
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;
int array[40003];
vector<int> q;
int search(int k,int l,int r)
{
if(l == r)
{
if(q[l] == k)
{
return l;
}
else if(l == 0 && k<q[0])
{
return l;
}
return l+1;
}
int mid = (l + r + 1)/2;
if(k<q[mid])
{
return search(k,l,mid-1);
}
else
{
return search(k,mid,r);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int t;
int n;
scanf("%d",&t);
while(t--)
{
q.clear();
scanf(" %d",&n);
memset(array,0,sizeof(array));
for(int i=0; i<n; i++)
{
scanf(" %d",&array[i]);
}
q.push_back(array[0]);
for(int i=1; i<n; i++)
{
int l = search(array[i],0,q.size()-1);
if(l > q.size()-1)
{
q.push_back(array[i]);
}
else
{
q[l] = array[i];
}
}
printf("%d\n",q.size());
}
return 0;
}
求最长单调递增子序列的长度还有其他方法,更多请参考:
http://blog.youkuaiyun.com/niuox/article/details/8710164
参考:
http://www.cnblogs.com/mycapple/archive/2012/08/22/2651453.html
http://www.cnblogs.com/mycapple/archive/2012/08/22/2651461.html