zoukankan      html  css  js  c++  java
  • HDU 4521 小明系列问题——小明序列【dp+线段树优化||最长递增序列】

    小明系列问题——小明序列

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 3361    Accepted Submission(s): 1058


    Problem Description
      大家都知道小明最喜欢研究跟序列有关的问题了,可是也就因为这样,小明几乎已经玩遍各种序列问题了。可怜的小明苦苦地在各大网站上寻找着新的序列问题,可是找来找去都是自己早已研究过的序列。小明想既然找不到,那就自己来发明一个新的序列问题吧!小明想啊想,终于想出了一个新的序列问题,他欣喜若狂,因为是自己想出来的,于是将其新序列问题命名为“小明序列”。

      提起小明序列,他给出的定义是这样的:
      ①首先定义S为一个有序序列,S={ A1 , A2 , A3 , ... , An },n为元素个数 ;
      ②然后定义Sub为S中取出的一个子序列,Sub={ Ai1 , Ai2 , Ai3 , ... , Aim },m为元素个数 ;
      ③其中Sub满足 Ai1 < Ai2 < Ai3 < ... < Aij-1 < Aij < Aij+1 < ... < Aim ;
      ④同时Sub满足对于任意相连的两个Aij-1与Aij都有 ij - ij-1 > d (1 < j <= m, d为给定的整数);
      ⑤显然满足这样的Sub子序列会有许许多多,而在取出的这些子序列Sub中,元素个数最多的称为“小明序列”(即m最大的一个Sub子序列)。
      例如:序列S={2,1,3,4} ,其中d=1;
      可得“小明序列”的m=2。即Sub={2,3}或者{2,4}或者{1,4}都是“小明序列”。

      当小明发明了“小明序列”那一刻,情绪非常激动,以至于头脑凌乱,于是他想请你来帮他算算在给定的S序列以及整数d的情况下,“小明序列”中的元素需要多少个呢?
     

    Input
      输入数据多组,处理到文件结束;
      输入的第一行为两个正整数 n 和 d;(1<=n<=10^5 , 0<=d<=10^5)
      输入的第二行为n个整数A1 , A2 , A3 , ... , An,表示S序列的n个元素。(0<=Ai<=10^5)
     

    Output
      请对每组数据输出“小明序列”中的元素需要多少个,每组测试数据输出一行。
     

    Sample Input
    2 0 1 2 5 1 3 4 5 1 2 5 2 3 4 5 1 2
     

    Sample Output
    2 2 1
     

    Source

    第一种解法:dp+线段树优化

    #include <iostream>  
    #include <cstdio>  
    #include <cstring>  
    #include <algorithm>  
    #include <cmath>  
    #include <queue>  
    #include <string>  
    #include <map>  
    #include <cstring>  
    #define INF 0x3f3f3f3f  
    #define ms(x,y) memset(x,y,sizeof(x))  
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> P;
    
    const int maxn = 110000;
    const int mod = 998244353;
    
    #define lson l,m,rt<<1  
    #define rson m+1,r,rt<<1|1  
    #define lz 2*u,l,mid
    #define rz 2*u+1,mid+1,r
    
    int a[maxn + 5], dp[maxn + 5];
    int sum[maxn << 2];
    
    void update(int pos, int c, int l, int r, int rt)
    {
    	sum[rt] = max(sum[rt], c);
    	if (l == r) return;
    	int m = (l + r) >> 1;
    	if (pos <= m) update(pos, c, lson);
    	else update(pos, c, rson);
    }
    
    int query(int L, int R, int l, int r, int rt)
    {
    	if (L > R) return 0;
    	if (L <= l && R >= r)
    	{
    		return sum[rt];
    	}
    	int m = (l + r) >> 1;
    	int ret = 0;
    	if (L <= m) ret = query(L, R, lson);
    	if (R > m) ret = max(ret, query(L, R, rson));
    	return ret;
    }
    
    
    int main()
    {
    	int n, d;
    	while (~scanf("%d%d", &n, &d))
    	{
    		ms(sum, 0);
    		for (int i = 1; i <= n; i++)
    			scanf("%d", &a[i]);
    
    		int ans = 0;
    
    		for (int i = 1; i <= n; i++)
    		{
    			if (i - d - 1>= 1)
    				update(a[i - d - 1] + 1, dp[i - d - 1], 1, maxn, 1);	//因为相隔大于d所以为i-d-1因为a[i]>a[i-1]所以要加1
    			dp[i] = query(1, a[i], 1, maxn, 1) + 1;
    			ans = max(ans, dp[i]);
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    


    第二种解法:dp的优化

    (未完待续)

    Fighting~
  • 相关阅读:
    thinkphp5 tp5 命名空间 报错 Namespace declaration statement has to be the very first statement in the script
    开启 php 错误 提示 php-fpm 重启 nginx 500错误 解决办法 wdlinux lnmp 一键包 php脚本无法解析执行
    js 设置 cookie 定时 弹出层 提示层 下次访问 不再显示 弹窗 getCookie setCookie setTimeout
    php 二维数组 转字符串 implode 方便 mysql in 查询
    nginx 重启 ps -ef|grep nginx kill -HUP 主进程号
    jquery bootstrap help-block input 表单 提示 帮助 信息
    jquery 倒计时 60秒 短信 验证码 js ajax 获取
    jQuery如何获取同一个类标签的所有的值 遍历
    linux下C语言文件操作相关函数
    gcc,gdb用法
  • 原文地址:https://www.cnblogs.com/Archger/p/8451602.html
Copyright © 2011-2022 走看看