[Topcoder]ZigZag(dp)

题目链接:https://community.topcoder.com/stat?c=problem_statement&pm=1259&rd=4493

题意:给一串数字,求出最长的波动序列。波动的定义是一个数相邻的两个数同时比他大或者同时比他小,形象的看成一个波动的三角函数吧。

定义dp(i)为到第i个数字时的最长波动序列长度,我们发现仅有一维的数组是存不下状态的,还应该再维护一个量,那就是第i个数字的时候他是波峰还是波谷。于是dp数组扩展成了dp(i,k),k可以取0或1分别表示是波峰还是波谷。更新的时候枚举第j(1~i-1)个数字,如果第i个数字和第j个数字不相同就更新,更新的时候要把i和j两个数字分别看成不同的极点。

 1 #include <string>
 2 #include <vector>
 3 #include <sstream>
 4 #include <algorithm>
 5 #include <iostream>
 6 #include <cstring>
 7 
 8 using namespace std;
 9 
10 class ZigZag {
11 public:
12     int longestZigZag(vector<int> sequence) {
13         int dp[101010][2];
14         int n = sequence.size();
15         int a[101010];
16         int ret = 0;
17         memset(dp, 0, sizeof(dp));
18         for(int i = 1; i <= n; i++) a[i] = sequence[i-1];
19         for(int i = 1; i <= n; i++) {
20             dp[i][0] = dp[i][1] = 1;
21             for(int k = 0; k < 2; k++) {
22                 for(int j = 1; j <= i; j++) {
23                     if(a[i] == a[j]) continue;
24                     if(k == 0) {
25                         if(a[i] < a[j])    dp[i][k] = max(dp[i][k], dp[j][!k]+1);
26                     }
27                     else {
28                         if(a[i] > a[j])    dp[i][k] = max(dp[i][k], dp[j][!k]+1);
29                     }
30                 }
31                 ret = max(ret, max(dp[i][0], dp[i][1]));
32             }
33         }
34         return ret;
35     }
36 };
原文地址:https://www.cnblogs.com/kirai/p/5604148.html