1.题目
给定一个长度为 N N N的数组,数组中的第 i i i 个数字表示一个给定股票在第 i i i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
输入格式
第一行包含整数
N
N
N,表示数组长度。
第二行包含 N N N 个不大于 10000 的正整数,表示完整的数组。
输出格式
输出一个整数,表示最大利润。
数据范围
1
≤
N
≤
1
0
5
1≤N≤10^5
1≤N≤105
输入样例1:
6
7 1 5 3 6 4
输出样例1:
7
输入样例2:
5
1 2 3 4 5
输出样例2:
4
输入样例2:
5
7 6 4 3 1
输出样例2:
0
2.基本思想
法一:贪心
O(n)
- 因为不限制交易次数,那么凡是存在price[i] > price[i-1]情形时 即后一天的价格比前一天的价格高,我们就可以获得利润。
法二:DP
1.状态表示集合:考虑前
i
天的股市 第i
天中持股状态为j
(j=0,未持股,j=1 持股)
属性:Max2.状态计算
3.代码实现
贪心
import java.util.Scanner;
public class Main{
static int N=100010;
static Scanner sc=new Scanner(System.in);
static int[] price =new int[N];
public static void main(String args[]){
int n=sc.nextInt();
for(int i=1;i<=n;i++) price[i]=sc.nextInt();
int res=0;
for(int i=1;i+1<=n;i++){
int profit = price[i+1]-price[i];
if(profit>0) res+=profit;
}
System.out.println(res);
}
}
DP
import java.util.Scanner;
public class _1055股票买卖Ⅱ {
static int N = 100010;
static Scanner sc = new Scanner(System.in);
static int[][] f = new int[N][2];
static int[] price = new int[N];
public static void main(String[] args) {
int n = sc.nextInt();
f[0][1]=Integer.MIN_VALUE;// 注意需要初始化
//因为f[0][1]代表考虑前 0天,状态是已经买入,这是一个不合法状态。第一次买入至少是在第 1天
//如果不把它初始化为负无穷,f[1][0]就会更新成f[0][1] + w[1],也就是w[1]但是f[1][0]实际意义是第 1天不买入股票,那么收益就是 0,而不是w[i]
for (int i = 1; i <= n; i++) price[i] = sc.nextInt();
for (int i = 1; i <= n; i++) {
f[i][0] = Math.max(f[i - 1][0], f[i - 1][1] + price[i]);
f[i][1] = Math.max(f[i - 1][1], f[i - 1][0] - price[i]);
}
System.out.println(f[n][0]);
}
}