动态规划初级练习(一):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;

}

 

 

 

你可能感兴趣的:(动态规划)