惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
Spread Privacy
Spread Privacy
T
Threatpost
C
Cisco Blogs
P
Palo Alto Networks Blog
AI
AI
Cyberwarzone
Cyberwarzone
NISL@THU
NISL@THU
P
Privacy & Cybersecurity Law Blog
G
GRAHAM CLULEY
Simon Willison's Weblog
Simon Willison's Weblog
T
Tor Project blog
Latest news
Latest news
AWS News Blog
AWS News Blog
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
WordPress大学
WordPress大学
Vercel News
Vercel News
S
Securelist
爱范儿
爱范儿
J
Java Code Geeks
Know Your Adversary
Know Your Adversary
S
Schneier on Security
Hugging Face - Blog
Hugging Face - Blog
F
Fortinet All Blogs
Last Week in AI
Last Week in AI
D
DataBreaches.Net
宝玉的分享
宝玉的分享
D
Darknet – Hacking Tools, Hacker News & Cyber Security
MongoDB | Blog
MongoDB | Blog
Engineering at Meta
Engineering at Meta
K
Kaspersky official blog
美团技术团队
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
量子位
博客园_首页
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
Google Online Security Blog
Google Online Security Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
腾讯CDC
T
Threat Research - Cisco Blogs
雷峰网
雷峰网
有赞技术团队
有赞技术团队
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy International News Feed
S
Security Affairs

博客园 - 谢绝围观

LeetCode 910. Smallest Range II EAC 抓取CD为AAC文件 Binary Indexed Tree (Fenwick Tree) Lint Code 1365. Minimum Cycle Section LintCode 896. Prime Product 简明题解 Windows下安装配置MinGW GCC调试环境 详解LeetCode 137. Single Number II LeetCode 309. Best Time to Buy and Sell Stock with Cooldown LeetCode 84. Largest Rectangle in Histogram 修改注册表删除Windows资源管理器 “通过QQ发送” 右键菜单项 LeetCode 312. Burst Balloons LeetCode 287. Find the Duplicate Number LeetCode 10. Regular Expression Matching LeetCode 117. Populating Next Right Pointers in Each Node II 在Windows Azure VM下搭建SSTP VPN - 谢绝围观 利用.NET Code Contracts实现运行时验证 Log4net 配置实例 解决Windows Server 2012 下利用RRAS创建VPN断线的问题 - 谢绝围观 慎用静态类static class
UVa 1471 - Defense Lines
谢绝围观 · 2017-12-18 · via 博客园 - 谢绝围观

原题链接

紫书的例题,不错的题。可以用O(n)的空间one pass解决,因为有二分,时间应该是O(nlogn)。

基本思路是用当前递增子序列的起始元素去匹配之前递增子序列的末尾元素,如果起始元素 A[i] > 末尾元素A[j] 则两个子序列可以组合成新的子序列。

关键点:

  1. 每种长度的子序列只需保留末尾元素最小的一个,所以只需一个数组minR即可,index是长度,value是该长度的子序列的有末尾元素。
  2. 当找到一个新的子序列后,需要从这个子序列的开头开始遍历一遍,假设当前元素下标为k:1)以k开始的子序列(也即当前子序列的右半部份)可能可以匹配到新的子序列,因为A[k] > A[k-1]; 2) 以k结束的子序列子序列(也即当前子序列的左半部份)可能可以更新已有的子序列(长度一样,末尾元素更小)。换言之,我们还需要考虑当前子序列的子序列,而不是仅仅将当前找到的子序列当作整体处理。

上代码。一般的case可以过,提交两次都WA,也懒得调试了,主要看气质吧。

 1 class UVa1471{
 2 public:
 3     int FindLongestCombinedSubSeq(vector<int> &v){
 4         size_t len = v.size();
 5         // Index is the length of existing sub sequence, value is the rightmost value of the subsequence
 6         vector<int> minR(len, RMAX);
 7         int prev = INT_MIN, seq = 0, maxSeqLen = 0;
 8         for(size_t i = 0; i < len; i++){
 9             if(v[i] > prev){
10                 seq++;
11             }else{
12                 int lo = i - seq;
13                 for(int k = 0; k < seq; k++){
14                     int num = v[lo + k];
15                     // Consider right part of current sequence, num as left element, find previous sub sequcence which right end element < num.
16                     int prevSeqLen = binSearch(minR, num);
17                     maxSeqLen = max(maxSeqLen, prevSeqLen + seq - k);
18                     // Consider left part of current sequence, num as right element, replace existing sub sequence if its righ end element > num.
19                     int leftPartLen = k + 1;
20                     minR[leftPartLen] = min(minR[leftPartLen], num);
21                 }
22                 seq = 1;
23             }
24             prev = v[i];
25         }        
26         int lo = len - seq;
27         for(int k = 0; k < seq; k++){
28             int prevSeqLen = binSearch(minR, v[lo + k]);
29             maxSeqLen = max(maxSeqLen, prevSeqLen + seq - k);
30         }        
31         return maxSeqLen;
32     }
33     
34 private:
35     const int RMAX = 0x3f3f3f3f;
36     int binSearch(vector<int> &v, int k){
37         size_t lo = 0, hi = v.size() - 1;
38         // invariant: the largest element < k is in [lo, hi]
39         while(lo < hi){
40             size_t m = lo + (hi - lo + 1)/2;
41             if(v[m] >= k){
42                 hi = m - 1;
43             }else{
44                 lo = m;
45             }
46         }
47         return lo;
48     }
49 };

 参考:http://blog.csdn.net/keshuai19940722/article/details/39297525