题目链接:https://vjudge.net/contest/228455#problem/B

转载于:https://blog.csdn.net/a709743744/article/details/51765252

题目大意:

求最长上升子序列,其中子序列中相邻的两个数的下标差要超过k

解题分析:

子序列中相邻的两个数的下标要超过k,要想满足这个条件我们可以按下面的思路想:

首先nlogn的LIS是毫无疑问的,然后再这个算法中,我们每次二分找到当前数的位置,如果数组中的数比当前数大的话就更新数组

所以我们可以稍微改一下上述步骤,当我们二分计算当前数的位置时,只是把当前数应该在数组中的位置保存下来,当前只更新在i - k之前的那个数,

这样我们就可以保证每次二分查找时,数组中的所有数的下标都比当前的下标少至少k.

然而我还是没有弄懂,先记录着吧。

这是我的代码,用结构体,然后套用了一下LIS模板,不知道为什WA了

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1e5 + 100;
int n, d;
struct node
{int val, ord;
}arr[MAXN],lis[MAXN];int find(int l, int r, int key)
{if (l == r)return l;int mid = (l + r) >> 1;if (key>lis[mid].val)return find(mid + 1, r, key);else return find(1, mid, key);
}int main()
{while (scanf("%d %d", &n, &d) != EOF){        //注意是下标之差大于d,而不是值之差大于dmemset(arr, 0, sizeof(arr));for (int i = 1; i <= n; i++) {scanf("%d", &arr[i].val);arr[i].ord = i;}int len = 0;for (int i = 1; i <=n; i++){if (i == 1)lis[++len] = arr[i];else if (arr[i].val > lis[len].val) {if ((arr[i].ord - lis[len].ord) > d)lis[++len] = arr[i];}else{int j = find(1, len, arr[i].val);if (j != len){if (j == 1){if ((lis[2].ord - arr[i].ord) > d)lis[j] = arr[i];}else{if ((lis[j + 1].ord - arr[i].ord) > d && (arr[i].ord - lis[j - 1].ord) > d)lis[j] = arr[i];}}}    }printf("%d\n", len);}return 0;
}

View Code

AC的LIS解法

#include<iostream>
#include<cstring>
#include<cstdio>
#include <algorithm>
#define maxn 100005
using namespace std;
int a[maxn], b[maxn], p[maxn];
int n, d;int find(int p)   //二分查找<=p的位置+1
{int l, r, mid;l = 1, r = n, mid = (l + r) >> 1;while (l <= r){if (p>b[mid]) l = mid + 1;else if (p<b[mid]) r = mid - 1;else return mid;mid = (l + r) >> 1;}return l;
}int LIS(){int i, j, ans = 0;for (i = 1; i <= n; i++){p[i] = find(a[i]);         //p[i]存的是a[i]在上升数组中的位置ans = max(ans, p[i]);j = i - d;if (j>0) b[p[j]] = min(b[p[j]], a[j]);}return ans;
}int main()
{int i, res;while (cin >> n >> d){for (i = 1; i <= n; i++){scanf("%d", &a[i]);b[i] = maxn;}res = LIS();printf("%d\n", res);}return 0;
}

dp    AC解法

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 100000 + 10;
int a[maxn], dp[maxn], g[maxn], n, k;int main()
{while (~scanf("%d%d", &n, &k)){int ans = -1;memset(dp, 0, sizeof(dp));memset(g, INF, sizeof(g));for (int i = 1; i <= n; i++)scanf("%d", &a[i]);for (int i = 1; i <= n; i++){                                                                   //延迟p位更新             //为什么我感觉i>k+1以后还是连续的,下标并没有相差k啊???搞不懂if (i - k - 1>0)  g[dp[i - k - 1]] = min(a[i - k - 1], g[dp[i - k - 1]]);        // i-p>1 是因为下标j范围为1<j<=mdp[i] = lower_bound(g + 1, g + 1 + n, a[i]) - g;       //先记录下a[i]在g数组中的位置       ans = max(ans, dp[i]);}cout << ans << endl;}return 0;
}

2018-05-17

转载于:https://www.cnblogs.com/00isok/p/9050736.html

【hdu】4521 小明序列【LIS变种】【间隔至少为d】相关推荐

  1. hdu4521 小明系列的问题——小明序列(LIS变种 (段树+单点更新解决方案))

    链接: huangjing 题目:中文题目 思路: 1:这个题目假设去掉那个距离大于d的条件,那么必定是一个普通的LIS.可是加上那个条件后就变得复杂了.我用的线段树的解法. . .就是採用延迟更新的 ...

  2. hdu 4521 小明序列

    怒 马 一 发! 看了好久,师哥说超!纲!了! 等到会了再回来补坑○| ̄|_

  3. HDU 4521 小明系列问题——小明序列 LIS+动态规划

    HDU 4521小明系列问题--小明序列 Time Limit:1000MS    Memory Limit:32768KB    64bit IO Format:%I64d & %I64u ...

  4. 小明系列问题――小明序列(LIS)

    小明系列问题――小明序列 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit ...

  5. HDU 2096 小明A+B(%的运用)

    传送门: 小明A+B Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. hdu 4501 小明系列故事——买年货 多重背包

    小明系列故事--买年货                                                                          Time Limit: 500 ...

  7. HDU - 4511 小明系列故事——女友的考验(AC自动机+dp)

    题目链接:点击查看 题目大意:小明在点 1 而小明的女朋友在点 n ,现在小明要去找女朋友,满足以下两个条件: 途径的序号满足严格递增 小明的女朋友给小明提出了 m 条路径是不允许走的 在满足上述两条 ...

  8. hdu 4506 小明系列故事——师兄帮帮忙

    小明系列故事--师兄帮帮忙 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total ...

  9. HDU 4506 小明系列故事——师兄帮帮忙

    小明系列故事--师兄帮帮忙 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) To ...

最新文章

  1. 每年节省170万美元的文档预览费用,借助机器学习的DropBox有多强​?
  2. 新手探索NLP(一)
  3. 哈夫曼树+密码题+TTL
  4. php安装openssl 扩展
  5. 当不能用for等循环时,可以考虑递归
  6. 阿里P8亲自教你!mysql列转行
  7. jQUery中closest和parents的主要区别是
  8. LeetCode 2002. 两个回文子序列长度的最大乘积(状态压缩+枚举状态子集+预处理)
  9. 防蓝光膜真的能阻挡蓝光,减小辐射吗?
  10. 很多人理解互联网是“年轻化”
  11. UVA1091 WF4786 Barcodes【编码检查】
  12. mz04那智不二越机器人编程_买买买!这些炫酷的机器人已加入进博会“购物车”!...
  13. 软考(6)--数据库
  14. 阿里云中获取文件及目录列表的方法
  15. 时间序列数据的正态性检验
  16. 亿能第二期测试沙龙-《企业自动化测试专题研讨会》4月中旬举行
  17. word 插入单页页脚
  18. 人工智能 | ShowMeAI资讯日报 #2022.06.07
  19. TD回撤/斐波那契回撤
  20. Cesium加载OpenStreetMap

热门文章

  1. iOS开发:使用Block在两个界面之间传值(Block高级用法:Block传值)
  2. eclipse中新建android项目,不自动生成R.java
  3. 绿色版mysql使用方法
  4. 给博客增加了一个主题Nautica02Liquid
  5. AJAX范例大搜罗(转载)
  6. linux字符界面教程,打造字符界面的多媒体Linux系统
  7. 如何使您的Kotlin Android动画可访问
  8. kotlin ++ --_顺便说一句-探索Kotlin代表团
  9. 如何仅使用HTML和JavaScript构建简单的URL缩短器
  10. 使用Tape和Vue Test Utils编写快速的Vue单元测试