• 题目1537:买卖股票


    题目描述:
    给定一个大小为n的数组,数组的元素a[i]代表第i天的股票价格。
    设计一个算法,计算在最多允许买卖k次(一买一卖记为一次)的条件下的最大收益。
    需要注意的是,你不能同时拥有两份股票。也就是说在下次买入前,你必须把手头上原有的股票先卖掉。
    输入:
    输入可能包含多个测试案例。
    对于每个测试案例,输入的第一行为两个整数n和k(1<=n,k<=1000)。
    输入的第二行包括n个整数,范围在[0,10000),代表数组中的元素。
    输出:
    对应每个测试案例,输出最大获益。
    样例输入:
    5 1
    3 4 5 1 4
    7 2
    1 2 3 5 6 1 7
    样例输出:
    3
    11
    来源:
    Leetcode 加强版本

    本来这一题完全没有思路的。主要是想到了用dp[i]表示前i天的最大收益。但是不知道怎么处理k次。。还是做题太少。这种有两个条件限制的题明显用dp[i][j]来做。比如0-1背包问题,最原始的想法是考虑到背包体积v和i件物品dp[i][j]表示体积不超过j时,前i个物品能达到的最大价值。LCS问题,考虑到两个字符串dp[i][j]表示S1的前x个字符和S2的前j个字符最长公共子序列。

    所以这题dp[i][j]表示前j天完成i次交易获得的最大收入。

    1) dp[0][j] = 0; dp[i][0] = 0;dp[i][1] = 0;

    2)dp[i][j] = max{dp[i][j-1], max{dp[i - 1][k] + a[j] - a[k]}(1<= k <j)} (1<= i<=交易次数, 2<=j<=n)

    总状态数为O(n * k).状态转移方程可以对每个i,维护一个max = dp[i -1][k] - a[k],这样转移次数为O(1),时间复杂度为O(n * k),否则遍历为O(n),时间复杂度为O(n^2 * k)会超时。

    AC代码:

    #include <stdio.h>
     
    const int MAX = 1001;
     
    int dp[MAX][MAX];
     
    int main()
    {
        int list[1010];
        int n, k;
        while(scanf("%d %d", &n, &k) == 2)
        {
            for(int i = 1; i <= n; i++)
                scanf("%d", &list[i]);
            for(int i = 0; i <= n; i++)
            {
                dp[0][i] = 0;
            }
            for(int i = 0; i <= k ;i ++)
            {
                dp[i][0] = 0;
                dp[i][1] = 0;
            }
            for(int i = 1; i <= k; i++)
            {
                int max = dp[i - 1][1] - list[1];
                for(int j = 2; j <= n; j++)
                {
                    dp[i][j] = dp[i][j - 1] > (max + list[j]) ? dp[i][j - 1] : (max + list[j]);
                    int tmp = dp[i - 1][j] - list[j];
                    max = tmp > max ? tmp : max;
                }
            }
            printf("%d
    ", dp[k][n]);
        }
        return 0;
    }
    /**************************************************************
        Problem: 1537
        User: Qinger
        Language: C++
        Result: Accepted
        Time:40 ms
        Memory:4936 kb
    ****************************************************************/
  • 相关阅读:
    LeetCode Subsets II
    LeetCode Rotate Image
    LeetCode Palidrome Number
    LeetCode Generate Parentheses
    LeetCode Maximum Subarray
    LeetCode Set Matrix Zeroes
    LeetCode Remove Nth Node From End of List
    Linux Loop设备 使用
    Linux 文件系统大小调整
    LeetCode N-Queens II
  • 原文地址:https://www.cnblogs.com/xyqhello/p/3591672.html
Copyright © 2020-2023  润新知