给定一个长度为 N 的数组,数组中的第 i 个数字表示一个给定股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润,你最多可以完成 k 笔交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。一次买入卖出合为一笔交易。
输入格式
第一行包含整数 N 和 k,表示数组的长度以及你可以完成的最大交易数量。
第二行包含 N 个不超过 10000 的正整数,表示完整的数组。
输出格式
输出一个整数,表示最大利润。
数据范围
1≤N≤105,
1≤k≤100
输入样例1:
3 2
2 4 1
输出样例1:
2
输入样例2:
6 2
3 2 6 5 0 3
输出样例2:
7
样例解释
样例1:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。
样例2:在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。共计利润 4+3 = 7.
题解
f[k][i][0]表示第i天已经进行了k次交易并且手里没货的最大收益
f[k][i][1]表示第i天已经进行了k次交易并且手里有货的最大收益
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int KN = 110;
int f[KN][N][2];
int a[N];
const int INF = 0x3f3f3f3f;
int main(){
int n,K;
cin>>n>>K;
for(int i = 0;i <= K;i ++)f[i][0][1] = -INF;
for(int i = 1;i <= n;i ++){
cin >> a[i];
for(int k = 0;k <= K;k ++){
f[k][i][0] = f[k][i - 1][0];
if(k >= 1)f[k][i][0] = max(f[k][i][0],f[k - 1][i - 1][1] + a[i]);
f[k][i][1] = max(f[k][i - 1][1],f[k][i - 1][0] - a[i]);
}
}
cout<<f[K][n][0];
return 0;
}