• HDOJ 1003 Max Sum(线性dp)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003

    思路分析:该问题为最大连续子段和问题,使用动态规划求解;

    1)最优子结构:假设数组为A[0, 1, 2,….., n],在所有的可能的解中,即解空间中找出所有的解,可以知道,所有的解都为以A[j](j = 0, 1, …, n)

    为尾的连续子段,则假设dp[j]表示以在数组A[1, 2, …, j]中以A[j]结尾的字段的最大的和,我们就可以刻画子空间中的所有解的特征;如果

    dp[j] > 0,则dp[j + 1] = dp[j] + A[j + 1],否则dp[j + 1] = A[j + 1];对于该最优子结构的证明可以使用反证法来证明;

    2)重叠子问题:明显,对于该问题的递归算法会反复求解相同的子问题,所有具有重叠子问题的性质;

    代码如下:

    #include <iostream>
    using namespace std;
    
    const int MAX_N = 100000 + 10;
    int arr[MAX_N];
    int pos_start, pos_end, num_arr;
    
    int Solve()
    {
        int l = 1, r = 1;
        int ans = INT_MIN, sum = 0;
    
        for (int i = 1; i <= num_arr; ++i)
        {
            if (sum >= 0)
            {
                r = i;
                sum += arr[i];
            }
            else
            {
                l = r = i;
                sum = arr[i];
            }
    
            if (sum > ans)
            {
                pos_start = l;
                pos_end = r;
                ans = sum;
            }
        }
        return ans;
    }
    
    int main()
    {
        int case_num, case_id = 0;
        int ans = 0;
    
        scanf("%d", &case_num);
        while (case_num--)
        {
            scanf("%d", &num_arr);
            for (int i = 1; i <= num_arr; ++i)
                scanf("%d", &arr[i]);
            ans = Solve();
    
            printf("Case %d:
    ", ++case_id);
            printf("%d %d %d
    ", ans, pos_start, pos_end);
            if (case_num > 0)
                printf("
    ");
        }
    
        return 0;
    }

     

  • 相关阅读:
    Wannafly挑战赛14 F.细胞
    D 勤奋的杨老师(二)(最小割)
    三分算法求最值
    初识最大流
    初识数据结构
    决策型DP
    哈希表
    【BZOJ】1878: [SDOI2009]HH的项链 (主席树)
    【HDU】1520 Anniversary party(树形dp)
    【UVa】1606 Amphiphilic Carbon Molecules(计算几何)
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4523445.html
Copyright © 2020-2023  润新知