POJ 2479(动态规划)

来源:互联网 发布:海意it 编辑:程序博客网 时间:2024/06/05 19:17

一、题目大意

求连续的整数中两段不重叠的子串的最大值,运用动态规划可以很好地解决。


二、知识点回顾

先看看求一段子串的最大值是如何计算的。

读入的整数存在数组an中,设立新数组bn,b[i]存放以第i个元素结尾的子串的最大值,很显然,可以得出DP方程:b[i]=max(a[i],b[i-1]+a[i])

程序如下:

#include <iostream>using namespace std;#define MAX  1000int main() {    int t;    cin>>t;    int n;    int a[MAX],b[MAX];    while(t--)    {        cin>>n;        for (int i = 0; i <n ; ++i) {            scanf("%d",&a[i]);        }        b[0] = a[0];        for (int j = 1; j <n ; ++j) {            b[j] = max(a[j],b[j-1]+a[j]);        }        int max = -9999999;        for (int k = 0; k <n ; ++k) {            if (b[k]>max)                max = b[k];        }        cout << max << endl;    }}

三、题目分析

除了源数据的数组a以外,设立三个数组,分别是b,c,d;

b[i]代表以b[i]元素结尾的前i+1个元素的最大和,c[i]代表以c[i]元素开始的最大元素和,d[i]用来保存第i+1个元素到最后一个元素的最大元素和,

最终结果就是b[i]+d[i+1]的最大值

代码如下:

#include <iostream>using namespace std;#define MAX  50010int main() {    int t;    cin >> t;    int n;    int a[MAX], b[MAX], c[MAX], d[MAX];    while (t--) {        scanf("%d", &n);        for (int i = 0; i < n; ++i) {            scanf("%d", &a[i]);        }        b[0] = a[0];        for (int j = 1; j < n; ++j) {            b[j] = max(a[j], b[j - 1] + a[j]);        }        c[n - 1] = a[n - 1];        for (int k = n - 2; k > 0; k--) {            c[k] = max(a[k], c[k + 1] + a[k]);        }        d[n - 1] = c[n - 1];        d[0] = 0;        for (int l = n - 2; l > 0; l--) {            d[l] = max(c[l], d[l + 1]);        }        int temp = -0x3f3f3f;        for (int m = 0; m < n-1; m++) {            temp = max(temp, d[m + 1] + b[m]);        }        printf("%d\n", temp);    }}

1 0
原创粉丝点击