HDU 4521 小明系列问题——小明序列 DP – LIS加强版 #by Plato

HDU 4521 小明系列问题——小明序列  DP – LIS加强版 #by Plato

http://acm.hdu.edu.cn/showproblem.php?pid=4521

 

题意:给个序列,求其最长上升序列(LIS)。增加了个额外的条件,子序列中相邻两个距离必须大于D。

Idea: 数据比较大,N = 10^5,得用 NlogN的算法,并且考虑那个额外的条件。

大致的,增加一个辅助数组,minv[j]代表[距离i距离大于D的]长度为j的子序列的 最小的尾巴。详细的懒写了。


#include <cstdio>
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
#define OP(s) cout<<#s<<"="<<s<<" ";
#define TP(i,j,k) cout<<#i<<"="<<i<<" "<<#j<<"="<<j<<" "<<#k<<"="<<k<<endl;
#define PP(s) cout<<#s<<"="<<s<<endl;
using namespace std;
const int INF = 1<<29;

int minv[100010];

int bsearch(int low,int high,int target)
{
    while (low < high)
    {
        int mid = (low + high + 1)>>1;
        if (minv[mid] < target)
            low = mid;
        else
            high = mid - 1;
    }

    return high;
}

int main()
{
    freopen("test.txt","r",stdin);
    int N,D;
    while (~scanf("%d%d",&N,&D))
    {
        static int a[100010];
        for (int i = 1;i <= N;i++)
            scanf("%d",a+i);

        static int f[100010];
        memset(f,0,sizeof(f));
        for (int i = 0;i < 100010;i++) minv[i] = INF;
        for (int i =1 ;i <= N;i++)
        {
            int k = bsearch(0,N,a[i]);
            f[i] = k+1;
            int j = i-D;
            if (j > 0)
            {
                int len = f[j];
                minv[len] = min(a[j],minv[len]);
            }
        }

        int ans = 0;
        for (int  i = 1;i <= N;i++)
            if (f[i] > ans) ans = f[i];
        cout<<ans<<endl;
    }


    return 0;
}



{

题外话:说下做那场马拉松的感受吧。

之前注册了马甲去看看了第一天的题目,后面几天的看了部分,周日是主场了。

7:05,到宿舍吧,开机。。。

A题,水。

E题,水。

D题,B题。

B题就是个加强的LIS,觉得可以做,去搜了下NlogN的算法,发现还要处理距离条件,考虑了会,最后还是没写。

看D题过了不少,开始去考虑了。分类讨论:M大于N的,只要切一下就好了;M小于N的话,至少要切(M-N)下。但是要高精度,于是去网上搜了个高精的模版,贴过了~~~

B题觉得写不了,就看C题了。看完就觉得是个较水的最短路,数据小,不用什么优化。不过处理输入的字符串稍有点恶心。

处理读入,Dijstra,然后自信地去提交。当时HDU交的人暴多,一直在排队。就没在意了,去逛了下,回来查代码发现有几处明显的代码错误,修改在提交。不过一直到结束,我第一个交的都在排队。

最后呢。。。华丽的WA了。再看题目,"如果在起点坐的是卧铺,则后面乘坐的车必须全是卧铺"k = 0,k = 1分别建图,补题了。还是WA了。再看题目“k=0表示该车只有硬座,k=1表示该车有卧铺也有硬座”,OK了。

}

你可能感兴趣的:(HDU 4521 小明系列问题——小明序列 DP – LIS加强版 #by Plato)