题文:
Avin is studying series. A series is called “wave” if the following conditions are satisfied:
- It contains at least two elements;
- All elements at odd positions are the same;
- All elements at even positions are the same;
- Elements at odd positions are NOT the same as the elements at even positions.
You are given a series with length n. Avin asks you to find the longest “wave” subseries. A subseries is a subsequence of a series.
Input
The first line contains two numbers n, c (1 ≤ n ≤ 100, 000, 1 ≤ c ≤ 100). The second line contains n integers whose range is [1, c], which represents the series. It is guaranteed that there is always a “wave” subseries.
Output
Print the length of the longest “wave” subseries.
Sample Input
5 3
1 2 1 3 2
Sample Output
4
题意
再给定序列中找满足条件的最长子序列,子序列要求最少两个元素,所有偶数下标位上元素都相同,所有奇数下标位上元素都相同。
感想
当时知道是DP,可是就是找不到思路,过后上网找题解也弄不懂大神们的思路,后来想了两天终于想出思路A了,终归还是自己能力不足,要再加把劲。
思路
1:DP的题目,切入点是问题的初始状态,这道题的初始状态显然为只有两个元素的时候(1个元素时不符合条件),这里设为(1, 2)
2:假设第三个数b为新的数,那么b不能和前面(1,2)构成更长的子序列,只能构成两个新子序列(1,b)和(2,b)
3:当数b为1时,可以延长(1,2),得到dp(1,2,1) = dp(1,2) + 1。由于所求子序列为重复的两个元素不断翻转,故而得出状态转移方程应为:
dp(a,b) = dp(b,a) + 1
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[110][110];
int book[110];
int main(){
int n, c;while(scanf("%d%d", &n, &c) == 2){
memset(dp, -1, sizeof(dp));memset(book, 0, sizeof(book));int num, len = 0;for(int i = 0; i < n; i++){
scanf("%d", &num);book[num] = 1;//记录前面出现过的数for(int j = 1; j <= c; j++){
if(j == num || book[j] == 0) continue;if(dp[num][j] == -1)//前面没有翻转的子序列dp[j][num] = 2;//初始化为2elsedp[j][num] = dp[num][j] + 1;len = max(len, dp[j][num]);}}printf("%d\n", len);}
}