5214. 最长定差子序列
Posted daker-code
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5214. 最长定差子序列相关的知识,希望对你有一定的参考价值。
这道题,比较有意思,他们说用c++的Map会好些很多,而且节省空间,奈何我不会啊(有兴趣的道友,而可自行实现)。
一道递推的题目,因t为不会c++的Map所以我只能用数组来实现,但是有负数啊,数组索引不能为负数啊,这可怎么办凉凉了。简单暴力的方法,直接加上最大边界值,数组开两倍大,相当于去掉了符号。这时候我们就可以开出我们的dp数组了。既然是递推那么就得有 递推公式 。也很简单, 最长啥啥啥的那不就是步长为 1 一次次累加的关系吗?而且还要最长,那肯定得要有max函数了。我们设dp[i]表示当前序列最后一个数是i的最大子序列长度,每一次i++之后我们都与上一次认定的“最长值”进行比较,如果中间断开,那么由于上一次的“最长值” 的索引由步长决定,且步长为固定值,所以断开后会自动重新计数。有这个规律我们可以很轻易的写出状态转移方程:
dp[i]=max(dp[i],dp[i-difference]+1);
当然这仅仅是动态转移方程,具体实现起来还是需要改动的。大家可以自己先试试如何实现,再来看代码。
1 /** 2 * @brief 最长定差子序列 3 * @note 一定要加10000 4 * @param arr: 给定序列 5 * @param arrSize: 序列长度 6 * @param difference: 定固差 7 * @author 杨文蓁的小迷弟 8 */ 9 int longestSubsequence(int* arr, int arrSize, int difference) 10 int ans = 0; 11 int dp[20002] = 0; 12 for (int i = 0; i < arrSize; i++) 13 14 arr[i] += 10000; 15 16 17 for (int i = 0; i < arrSize; i++) 18 19 int sum = arr[i] - difference; 20 if (sum > 20000 || sum < 0) 21 22 dp[arr[i]] = 1; 23 24 else 25 26 dp[arr[i]] = dp[arr[i]] > (dp[sum]+1) ? dp[arr[i]] : (dp[sum]+1); 27 28 ans = ans > dp[arr[i]] ? ans : dp[arr[i]]; 29 printf("%d\\n", ans); 30 31 32 return ans; 33
周赛不易,诸君共勉!
以上是关于5214. 最长定差子序列的主要内容,如果未能解决你的问题,请参考以下文章