大盗阿福
状态机
算法思路:
//状态表示:
// f[i]表示抢劫前i家店铺的收益
//状态计算
// 抢第i家: f[i - 2] + w[i]
// 不抢第i家:f[i - 1]
//状态分解:
// f[i] = 0:未选最后一个店铺
// f[i] = 1:选择最后一个店铺
//
//状态表示:
// f[i][j]:所有走了i步,且当前位于状态j的所有走法
//属性:
// max
//状态计算:
// f[i][0]: 最后一步0->0 | 最后一步1->0
// f[i - 1][0] | f[i-1][1]
// f[i][1]: 最后一步0->1
// f[i - 1][0] + w[i]
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010, INF = 0x3f3f3f;
int n;
int w[N], f[N][2];
int main(){
int T;
cin >> T;
while(T --){
cin >> n;
for(int i = 1; i <= n; i ++) cin >> w[i];
//状态机入口:从0开始,不能取到1
f[0][0] = 0, f[0][1] = -INF;
for(int i = 1; i <= n; i ++){
f[i][0] = max(f[i - 1][0], f[i - 1][1]);
f[i][1] = f[i - 1][0] + w[i];
}
cout << max(f[n][0], f[n][1]) << endl;
}
return 0;
}
股票买卖IV
状态机模型
//两种状态:
// k = 0: 手中无货
// k = 1:手中有货
//状态表示:f[i][j][k]:代表交易了i天,已经交易了j次,状态为k
//属性:max
//状态计算:
// f[i][j][0]: 最后一步 0 -> 0 | 最后一步 1 -> 0
// f[i - 1][j][0] | f[i - 1][j][1] + w[i]
//
// f[i][j][1]: 最后一步 1 -> 1 | 最后一步 0 -> 1
// f[i - 1][j][1] | f[i - 1][j - 1][0] - w[i]
//理解:
// 1->0:表示 手中有货 变为 手中无货,并且当前正在进行交易,还未交易完成,只有将w[i]加上才能够算交易完成
// 0->1:j表示正在进行第j次交易,当前正在交易的钱f[i][j][1] 等于 尚未交易的钱 减去 购买的钱
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100010, M = 110, INF = 0x3f3f3f;
int n, k;
int f[N][M][2];
int w[N];
int main(){
cin >> n >> k;
for(int i = 1; i <= n; i ++) cin >> w[i];
//初始化
memset(f, -INF, sizeof f);
for(int i = 0; i <= n; i ++) f[i][0][0] = 0;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= k; j ++){
f[i][j][0] = max(f[i - 1][j][0], f[i - 1][j][1] + w[i]);
f[i][j][1] = max(f[i - 1][j][1], f[i - 1][j - 1][0] - w[i]);
}
int res = 0;
for(int i = 1; i <= k; i ++) res = max(res, f[n][i][0]);
cout << res << endl;
return 0;
}
股票买卖V
股票买卖自动机
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100010;
int f[N][3];
int n;
int w[N];
int main(){
cin >> n;
for(int i = 1; i <= n; i ++) cin >> w[i];
memset(f, -0x3f3f3f, sizeof f);
f[0][2] = 0;
for(int i = 1; i <= n; i ++){
f[i][0] = max(f[i - 1][0], f[i - 1][2] - w[i]);
f[i][1] = f[i - 1][0] + w[i];
f[i][2] = max(f[i - 1][1], f[i - 1][2]);
}
cout << max(f[n][1], f[n][2]) << endl;
return 0;
}