hdu 4512 (LCIS)

来源:互联网 发布:网络扳手的意思 编辑:程序博客网 时间:2024/06/04 01:29

好久没写解题报告了,最近几周好忙。。。感觉是我进大学以来最忙的一段时间了,要给新生准备下周三比赛的题目,下周五要去南京赛区,回来之后马上就要期中考试了。。。不想挂科大哭


额,很早之前就看过关于LCIS的题目,但是依然理解不了,昨天在网上找了一些资料,我就直接看了那个O(n^2)的解法,有点小懂,但是对于其中的精髓依然陌生,我估计我只是记住了代码。。并不是真正的理解。不过慢慢来,加油!!


这道题,看完题目就可以知道是LCIS这种类型的,但是有个不好搞的地方就是如何判断前后两部分有无公共部分,也就是所选出的队伍中的人数是奇数还是偶数。

a[i], b[j], 本题中b[]就是a[]的倒序。

f[j]表示以b[j]为结尾的LCIS的最大长度。枚举断点将原队列分成两个队列再求两个队列的LCIS即可。


/*

 * 2013年10月27日13时40分10秒
 * LCIS的变形
 */
#include <stdio.h>
#include <string.h>

#define max(x, y) ((x)>(y)?(x):(y))

int a[205], f[205], n;

int LCIS(){
    memset(f, 0, sizeof(f));
    int i, j, k, ans=0;
    for (i=n; i>=1; i--) {
        k = 0;
        for (j=1; j<=i; j++) {
            if (a[i] == a[j]) {
                if (f[j] < f[k]+1) {
                    f[j] = f[k]+1;
                }
            }
            else if (a[i] > a[j]) {
                if (f[k] < f[j]) {
                    k = j;
                }
            }
            if (j < i) {
                ans = max(ans, f[j]*2);
            }
            else {
                ans = max(ans, f[j]*2-1);
            }
        }
    }

    return ans;
}

int main(void){
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        int i;
        for (i=1; i<=n; i++) {
            scanf("%d", &a[i]);
        }
        printf("%d\n", LCIS());
    }

    return 0;
}

原创粉丝点击