DP ——线性dp之LIS

POJ 1631

LIS解析:

LIS 是 longest Increasing Sequence
是一道典型的线性DP问题,有两种算法可以求
一种是n^2 的算法,
设a: 1-n 的序列
for i 1->n
for j 1->i dp[i] = 1
d[i] = max{dp[i],dp[j]+1(a[j] < a[i])}

另一种nlogn即可(隐形DP)
设a: 1-n 的序列
设b 记录长度为i子序列的最小尾数的序列//次序列单调
for i 1 -> n
k++ 或 binary;

AC code:

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
const int maxn = 4e4 + 100;

int a[maxn];
int b[maxn];


int binary(int st, int ed,int x)
{
    int mid;
    while(ed - st > 1)
    {
        mid = st + (ed-st)/2;
        if(b[mid] == x)  return mid;
        if(b[mid] < x)   st = mid;
        else             ed = mid;
    }
    return ed;
}
int LIS(int p)
{
   int k = 1;
   memset(b,0,sizeof(0));
   b[1] = a[0];
   for(int i = 1; i < p; i++)
   {
      int x = a[i];
      if(x > b[k])  b[++k] = x;
      else if(x < b[1]) b[1] = x;
      else
      {
      int j = binary(1,k,x);
      b[j] = min(b[j],x);
      }
   }
   return k;
}

int main()
{
    int n,p;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&p);
        for(int i = 0; i < p; i++)
        {
            scanf("%d",&a[i]);
        }
        int ans = LIS(p);
        printf("%d\n",ans);
    }
    return 0;
}



你可能感兴趣的:(动态规划)