zoukankan      html  css  js  c++  java
  • 动态规划初级练习(一):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
    ",z.longestZigZag(x));
        return 0;
    }
  • 相关阅读:
    Redis学习第二天
    Redis学习
    jQuery基础
    Hashtable 和 HashMap 的区别
    JSP页面乱码问题
    Day28 java8:Stream API
    转 链表中节点每k个一组反转
    day 27 lambda表达式(针对接口) & 函数式接口
    day20异常2
    day20 异常1
  • 原文地址:https://www.cnblogs.com/aboutblank/p/3304564.html
Copyright © 2011-2022 走看看