求最大子序列长度及最大字段和 --动态规划法C++语言

证明我就不够出了,我参考了这位博主的博客 点击打开链接,以及这是麻省理工算法导论关于该问题的讲解视频 点击打开链接,我就是参看以上看明白的。

以下代码目的仅为记录和分享,采用C++语言描述

一:最大子序列

腾讯出的题目是这样的:

1.递归描述:

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

int max_csubstr(const string &lhs, const string &rhs)
{
    if(lhs.size() == 0 || rhs.size() == 0)
        return 0;
    
    if(lhs.back() == rhs.back())
        return max_csubstr( lhs.substr(0, lhs.size()-1), 
                            rhs.substr(0, rhs.size()-1) )+ 1;
    else
        return max( max_csubstr(lhs.substr(0, lhs.size()),
                               rhs.substr(0, rhs.size()-1)),
                    max_csubstr(lhs.substr(0, lhs.size()-1),
                               rhs.substr(0, rhs.size())) );
}

int main()
{
    string sz; 
    
    while(cin >> sz){
        int len = (int)sz.size();
        if(len == 1)
            cout << len << endl;
        else{
            string rev_sz(sz);
            reverse(rev_sz.begin(), rev_sz.end());
            cout << len - max_csubstr(sz, rev_sz) << endl;
        }
    }   

    return 0;
}
2.非递归描述:
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;

#define MAX_SIZE 1001

int max_len[MAX_SIZE][MAX_SIZE];

int max_csubstr(const string &lhs, const string &rhs)
{
    int len_lhs = (int)lhs.size();
    int len_rhs = (int)rhs.size();

    memset(max_len, 0, MAX_SIZE * MAX_SIZE);

    for(int i=1; i<=len_lhs; ++i){
        for(int j=1; j<=len_rhs; ++j){
            if(lhs[i-1] == rhs[j-1])
                max_len[i][j] = max_len[i-1][j-1] + 1;
            else
                max_len[i][j] = max(max_len[i-1][j], max_len[i][j-1]);
        }
    }   

    return max_len[len_lhs][len_rhs];
}

int main()
{
    string sz; 

    while(cin >> sz){
        int len = (int)sz.size();
        if(len == 1)
            cout << len << endl;
        else{
            string rev_sz(sz);
            reverse(rev_sz.begin(), rev_sz.end());
            cout << len - max_csubstr(sz, rev_sz) << endl;
        }
    }   
    return 0;
}
3.输出结果:

二:最大字段和

问题描述:
给定由n个整数(包含负整数)组成的序列a1,a2,...,an,求该序列子段和的最大值。

当所有整数均为负值时定义其最大子段和为0。
依此定义,所求的最优值为:
 
例如,当(a1,a2 , a3 , a4 , a5 ,a6)=(-2,11,-4,13,-5,-2)时,

最大子段和为:

11+(-4)+13 =20


代码如下:

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

int find_max_add(vector<int> vec, const int size, int *start, int *end)
{
    if(size == 0)
        return -1; 

    int final_max = vec[0];
    if(size != 1){ 
        int cur_start = 0;
        int cur_end = 0;
    
        for(int i=0; i<size; ++i){
            int cur_max = vec[i];
            cur_start = i;
            for(int j=i+1; j<size; ++j){
                cur_max += vec[j];  
                if(cur_max > final_max){
                    final_max = cur_max;
                    *start = cur_start;
                    *end = j;
                }
            }
        }
    }   
    return final_max;
}

int main()
{
    vector<int> vec;
    int val;
    while(cin >> val && val != -1){
        vec.push_back(val);
    }   
    
    int start = 0;
    int end = 0;
    int found = find_max_add(vec, vec.size(), &start, &end);
    if(found != -1) 
        cout << start << "->" << end << ":" << found << endl;
    else
        cout << "input error." << endl;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值