2019CCPC-江西省赛(重现赛)D - Wave HDU - 6570

题文:

Avin is studying series. A series is called “wave” if the following conditions are satisfied:

  1. It contains at least two elements;
  2. All elements at odd positions are the same;
  3. All elements at even positions are the same;
  4. 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 <= 100; j++){
                if(j == num || book[j] == 0) continue;
                if(dp[num][j] == -1)//前面没有翻转的子序列
                    dp[j][num] = 2;//初始化为2
                else
                    dp[j][num] = dp[num][j] + 1;
                len = max(len, dp[j][num]);
            }
        }
        printf("%d\n", len);
    }
}
发布了37 篇原创文章 · 获赞 1 · 访问量 1318

猜你喜欢

转载自blog.csdn.net/qq_34727886/article/details/104293456