动态规划初级练习(一):ZigZag

Problem Statement

    

A sequence of numbers is called a zig-zag sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a zig-zag sequence.

For example, 1,7,4,9,2,5 is a zig-zag sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, 1,4,7,2,5 and 1,7,4,5,5 are not zig-zag sequences, the first because its first two differences are positive and the second because its last difference is zero.

Given a sequence of integers, sequence, return the length of the longest subsequence of sequence that is a zig-zag sequence. A subsequence is obtained by deleting some number of elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.

Definition

    
Class: ZigZag
Method: longestZigZag
Parameters: vector <int>
Returns: int
Method signature: int longestZigZag(vector <int> sequence)
(be sure your method is public)
    
 

Constraints

- sequence contains between 1 and 50 elements, inclusive.
- Each element of sequence is between 1 and 1000, inclusive.

 

题目中ZigZag序列即“小-大-小-大-小-大-小”,使用两个数组pos[i],neg[i]分别表示当前数字sequence[i]以‘大’结尾,以‘小’结尾。

要求轮流变大变小的最长序列,即最长递增子序列的变种。

例如序列: 1 17 5 10 13 15 10 5 16 8 

i        = 0  1   2  3   4   5   6   7  8   9
sequence = 1  17  5  10  13  15  10  5  16  8 
pos[i]   = 1  2   2  4   4   4   4   2  6   6    
neg[i]   = 1  1   3  3   2   2   5   5  3   7

首先,令pos[i]=neg[i]=1

递推公式

 

  sequence[i]>sequence[j], pos[i]=max(neg[j]+1,pos[i])-----------------------------①

 

  sequence[i]<sequence[j] , neg[i]=max(pos[j]+1,neg[i])----------------------------②

 

假设现在i=1 , j=0:

  由① 即pos[1]=max(neg[0]+1,pos[1])→pos[1]=2

现在i=2,j=0,1

  i=2,j=0:

    sequence[2]>sequence[0], 由① 即pos[2]=max(neg[0]+1,pos[2])→pos[2]=2

  i=2,j=1:

    sequence[2]<sequence[1], 由② 即neg[2]=max(pos[1]+1,neg[2])→neg[2]=3

现在i=3,j依次等于0,1,2

i=3,j=0:

  sequence[3]>sequence[0],由① 即pos[3]=max(neg[0]+1,pos[3])→pos[3]=2

i=3,j=1:

  sequence[3]<sequence[1], 由② 即neg[3]=max(pos[1]+1,neg[3])→neg[3]=3

  i=3,j=2:

    sequence[3]>sequence[2],由① 即pos[3]=max(neg[2]+1,pos[3])→pos[3]=4

以此类推...可以得出pos neg数组对应的各个数字相应的最长zigzag序列长度,取最大值就是要求的。

代码如下:

 

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <list>
#include <cctype>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define REP(i,j,k) for(int i = j ; i < k ; ++i)
#define MAXV (1000)
#define INF (0x6FFFFFFF)
using namespace std;
class ZigZag
{
public:
    int longestZigZag(vector <int> sequence)
    {
        int pos[55];
        int neg[55];
        int ans=0;
        for(int i=0; i<sequence.size(); i++)
        {
            pos[i]=1;
            neg[i]=1;
            for(int j=0; j<i; j++)
            {
                if(sequence[i]>sequence[j])
                    pos[i]=max(neg[j]+1,pos[i]);
                else if(sequence[i]<sequence[j])
                    neg[i]=max(pos[j]+1,neg[i]);
            }
            ans=max(ans,pos[i]);
            ans=max(ans,neg[i]);
        }
        return ans;
    }
};
int main()
{
    int _x[] = { 70, 55, 13, 2, 99, 2, 80, 80, 80, 80, 100, 19, 7, 5, 5, 5, 1000, 32, 32 };
    vector<int> x(_x , _x + sizeof(_x)/sizeof(_x[0]));
    ZigZag z;
    printf("%d\n",z.longestZigZag(x));
    return 0;
}

 

 

 

posted @ 2013-09-05 23:08  丶Blank  阅读(804)  评论(0编辑  收藏  举报