「动态规划」利用前辈们的胜利果实走好现在的路

/*************************************************************************
	> File Name: MaxSumOfSubarray.cpp
	> Author: Shaojie Kang
	> Mail: kangshaojie@ict.ac.cn 
	> Created Time: 2015年09月11日 星期五 09时13分02秒 
    > Problem:
        求出数组中子数组的最大和、最小和
 ************************************************************************/

#include<iostream>
#include<vector>
using namespace std;

// Solution 1: one dimention 
int GetMaxSum(vector<int> &nums)
{
    int size = nums.size();
    if(size == 0) return 0;
    if(size == 1) return nums[0];

    int sum = nums[0];
    int curSum = nums[0];
    for(int i = 1; i < size; ++i)
    {
        if(curSum < 0) curSum = 0;
        curSum += nums[i];
        if(curSum > sum) sum = curSum;
    }
    return sum;
}

int GetMinSum(vector<int> &nums)
{
    int size = nums.size();
    if(size == 0) return 0;
    if(size == 1) return nums[0];

    int sum = nums[0];
    int curSum = nums[0];
    for(int i = 1; i < size; ++i)
    {
        if(curSum > 0) curSum = 0;
        curSum += nums[i];
        if(curSum < sum) sum = curSum;
    }
    return sum;
}

// Solution 2: two dimentions
void GenerateArea(const vector<vector<int> > &nums, vector<vector<int> > &area)
{
    int rows = nums.size();
    int cols = nums[0].size();

    for(int j = 0; j < cols; ++j) 
    {
        if(j == 0) area[0][j] = nums[0][j];
        area[0][j] = area[0][j-1] + nums[0][j];
    }
    for(int i = 0; i < rows; ++i) 
    {
        if(i == 0) area[i][0] = nums[i][0];
        area[i][0] = area[i-1][0] + nums[i][0];
    }

    for(int i = 1; i < rows; ++i)
    {
        for(int j = 1; j < cols; ++j)
        {
            area[i][j] = area[i-1][j] + area[i][j-1] - area[i-1][j-1] + nums[i][j];
        }
    }
}

int GetBlockSum(const vector<vector<int> > &area, int rowUp, int rowDown, int col)
{
    int sum = area[rowDown][col] - area[rowUp][col] - area[rowDown][col-1] + area[rowUp][col-1];
}

int GetMaxSumII(vector<vector<int> > &nums)
{
    if(nums.empty()) return 0;
    int rows = nums.size();
    int cols = nums[0].size();
    vector<vector<int> > area(rows, vector<int>(cols, 0));
    GenerateArea(nums, area);
   
    int maxSum = nums[0][0];
    for(int rowUp = 0; rowUp < rows; ++rowUp)
    {
        for(int rowDown = rowUp; rowDown < rows; ++rowDown)
        {
            int sum = GetBlockSum(area, rowUp, rowDown, 0);
            int curSum = sum;
            for(int col = 1; col < cols; ++cols)
            {
                if(curSum < 0) curSum = 0;
                curSum += GetBlockSum(area, rowUp, rowDown, col);
                if(curSum > sum) sum = curSum;
            }
            if(sum > maxSum) maxSum = sum;
        }
    }
    return maxSum;
}

int main()
{
    int arr[] = {
        1, -2, 3, 5, -3, 2
    };
    vector<int> nums(arr, arr + sizeof(arr)/sizeof(int));
    cout<<GetMaxSum(nums)<<endl;
    cout<<GetMinSum(nums)<<endl;

    return 0;
}


/*************************************************************************
	> File Name: LongestIncreasingSubSequence.cpp
	$ Author: Shaojie Kang
	> Mail: kangshaojie@ict.ac.cn 
	> Created Time: 2015年09月11日 星期五 10时01分59秒 
    > Problem:
        求最长递增子序列
 ************************************************************************/

#include<iostream>
#include<vector>
using namespace std;

vector<int> GenerateLIS(const vector<int> &nums)
{
    vector<int> result;
    int size = nums.size();
    if(size == 0) return result;
    if(size == 1) return nums;
    vector<vector<int> > sequences(size);
    int longestIndex = 0;

    for(int i = 0; i < size; ++i)
    {
        sequences[i].push_back(nums[i]);
        for(int j = 0; j < i; ++j)
        {
            if(nums[i] > nums[j] && sequences[i].size()+1 > sequences[j].size())
            {
                sequences[i].clear();
                sequences[i].insert(sequences[i].begin(), sequences[j].begin(), sequences[j].end());
                sequences[i].push_back(nums[i]);
            }
        }
        if(sequences[i].size() > sequences[longestIndex].size()) 
            longestIndex = i;
    }
    return sequences[longestIndex];
}

int main()
{
    int arr[] = {
        3, 2, 9, 1, 4, 2, 6, 3, 7, 8, 9
    };
    vector<int> nums(arr, arr + sizeof(arr)/sizeof(int));
    vector<int> result = GenerateLIS(nums);

    for(int i = 0; i < result.size(); ++i)
        cout<<result[i]<<" ";
    cout<<endl;

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值