动态规划问题

//连续自数组的最大和问题,要求时间复杂度O(n)
bool g_InvalidInput = false;
int GreatestSumOfSubArray(int* array, int length){
    if (array == nullptr || length <= 0){
        g_InvalidInput = true;
        return 0;
    }
    int currentSum = 0;
    int GreatestSum = 0x80000000;
    for (int i = 0; i < length; ++i){
        if (currentSum <= 0)
            currentSum = array[i];
        else
            currentSum += array[i];
        if (currentSum > GreatestSum)
            GreatestSum = currentSum;
    }
    return GreatestSum;
}
//47:礼物的最大价值:利用二维数组存储中间结果,循环实现,动态规划法,递归公式:
// 在坐标(i, j)位置最大价值:f(i,j) = max(f(i, j-1), f(i-1, j)) + gift(i, j)
int getMaxValue_solution(const int* values, int rows, int cols){
    if (values == nullptr || rows <= 0 || cols <= 0){
        return 0;
    }
    int* maxValues = new int[rows * cols];
    for (int row = 0; row < rows; ++row){
        for (int col = 0; col < cols; ++col){
            int left = 0;
            int up = 0;
            if (row > 0)
                left = maxValues[(row - 1) * cols + col];
            if (col > 0)
                up = maxValues[row * cols + (col - 1)];
            maxValues[row * cols + col] = std::max(left, up) + values[row * cols + col];
        }
    }
    int maxValue = maxValues[(rows - 1)*cols + (cols - 1)];
    delete[] maxValues;
    maxValues = nullptr;

    return maxValue;
}
//把数字翻译成字符串,有多少种不同的翻译方法:递归分析,动态规划方法实现(循环),从右往左翻译
//f(i) = f(i+1) + g(i, i+1)*f(i+2), 其中g(i, i+1):numbers[i]numbers[i+1]组成的数字在10-25之间时为1,否则为0
int getTranslationsCount(const string& numbers){
    int length = numbers.length();
    if (length <= 0)
        return -1;
    int* counts = new int[length];
    int count = 0;
    for (int i = length - 1; i >=0; --i){
        count = 0;
        if (i == length - 1)
            count = 1;
        if (i < length - 1)
            count = counts[i + 1];
        if (i < length - 1){
            int digit1 = numbers[i] - '0';
            int digit2 = numbers[i + 1] - '0';
            int converted = digit1 * 10 + digit2;
            if (converted >= 10 && converted <= 25){
                if (i < length - 2)
                    count += counts[i + 2];
                else 
                    count += 1;
            }
        }
        counts[i] = count;
    }
    count = counts[0];
    delete[] counts;
    counts = nullptr;
    return count;
}
int getTranslationsCountPort(int number){
    if (number < 0)
        return -1;
    string numbersInString = to_string(number);
    return getTranslationsCount(numbersInString);
}
//48: 最长不含重复字符的子字符串(只含26个字母):递归分析, 循环实现,动态规划法 先写出递推公式 ,再写代码
int longestSubArrayWithoutDuplication(const string& str){
    if (str.length() <= 0)
        return -1;
    int curLength = 0;
    int MaxLength = 0;
    int* position = new int[26];
    for (int i = 0; i < 26; ++i)
        position[i] = -1;
    for (int i = 0; i < str.length(); ++i){
        if (position[str[i] - 'a'] == -1){
            position[str[i] - 'a'] = i;
            curLength++;
        }
        else {
            int prevIndex = position[str[i] - 'a'];
            int distance = i - prevIndex;
            if (distance <= curLength)
                curLength = distance;
            else
                curLength++;
        }
        if (curLength > MaxLength)
            MaxLength = curLength;
    }
    delete[] position;
    return MaxLength;
}
//丑数:求从小到达排列的第1500个丑数
//暴力枚举
bool isUgly(int number){
    while (number % 2 == 0)
        number /= 2;
    while (number % 3 == 0)
        number /= 3;
    while (number % 5 == 0)
        number /= 5;
    return (number == 1) ? true : false;
}
int getUglyNumber(int index){
    if (index <= 0)
        return -1;
    int number = 0;
    int uglyCount = 0;
    while (uglyCount < index){
        if (isUgly(number))
            uglyCount++;
        number++;
    }
    return number;
}
//利用丑数的定义,找出规律,每个丑数都是前面的丑数乘以2, 3, 5得到的,利用数组保存已排序的数组
int Min(int num1, int num2, int num3){
    int min = (num1 < num2) ? num1 : num2;
    min = (min < num3) ? min : num3;
    return min;
}
int getUglyNumber2(int index){
    if (index <= 0)
        return -1;
    int* pUglyNumbers = new int[index];
    pUglyNumbers[0] = 1;
    int nextUglyIndex = 1;
    int* pMultiply2 = pUglyNumbers;
    int* pMultiply3 = pUglyNumbers;
    int* pMultiply5 = pUglyNumbers;
    while (nextUglyIndex < index){
        int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5);
        pUglyNumbers[nextUglyIndex] = min;
        while (*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex])
            pMultiply2++;
        while (*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex])
            pMultiply3++;
        while (*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex])
            pMultiply5++;
        ++nextUglyIndex;
    }
    int UglyNumber = pUglyNumbers[index - 1];
    delete[] pUglyNumbers;
    return UglyNumber;
}
原文地址:https://www.cnblogs.com/songdanzju/p/7442000.html