2018 计蒜之道 初赛 第二场 A. 淘宝的推荐系统

这里写图片描述
这里写图片描述

非常容易想到dp的一个题目,因为n的总和时小于6*1e5的,且0<=d<=100,所以我们对于每个p[i]寻找所有的绝对值范围内的数,查看他们的序列。
dp[i] 表示到i的最长序列数。
所以就有

d p [ p [ i ] ] = m a x ( d p [ p [ i ] ] , d p [ p [ i ] j ] , d p [ p [ i ] + j ] ) ;

j时从0到D循环的,不过我们要针对p[i]已经出现过的情况判断一下,来确定你dp[p[i]]的初值,以及p[i]-j的是否越界进行判断一下。

代码如下:

#include<bits/stdc++.h>

using namespace std;
const int MAX = 100010;
const int MAX_N = 30010;
int book[MAX],p[MAX_N];
int N,D;
int main(void){
    int T;
    scanf("%d",&T);
    while(T--){
        memset(book,0,sizeof(book));
        scanf("%d%d",&N,&D);
        for(int i=1;i<=N;++i){
            scanf("%d",&p[i]);
            if(book[p[i]] == 0){
                book[p[i]] = 1;
            }
            else{
                book[p[i]] = book[p[i]]+1;
            }
            for(int j=1;j<=D;++j){
                if(p[i] - j >= 0 && book[p[i]-j]+1 > book[p[i]]){
                    book[p[i]] = book[p[i]-j]+1;
                }
                if(p[i] + j <= 100000 && book[p[i]+j]+1 > book[p[i]]){
                     book[p[i]] = book[p[i]+j]+1;
                }
            }
 //           printf("p = %d,book[p] = %d\n",p[i],book[p[i]]);
        }
        int res = 0;
        for(int i=0;i<=N;++i){
            res = max(book[p[i]],res);
        }
        printf("%d\n",res);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhao5502169/article/details/80580023
今日推荐