状态机:一系列有顺序的事件
1049. 大盗阿福 - AcWing题库
状态机做法
import java.util.*;
public class Main{
static int N = 100010;
static int[] w = new int[N];
static int[][] f = new int[N][2];
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t -- > 0){
int n = sc.nextInt();
for(int i = 1; i <= n; i ++){
w[i] = sc.nextInt();//读入数据
}
//状态机
for(int i = 1; i <= n; i ++){
f[i][0] = Math.max(f[i - 1][0], f[i - 1][1]);
f[i][1] = f[i - 1][0] + w[i];
}
System.out.println(Math.max(f[n][0], f[n][1]));//要比较两种情况的最大值
}
}
}
原dp做法
import java.util.*;
public class Main{
static int N = 100010;
static int[] w = new int[N];
static int[] f = new int[N];
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while(t -- > 0){
int n = sc.nextInt();
for(int i = 1; i <= n; i ++){
w[i] = sc.nextInt();//读入数据
}
f[1] = w[1];//初始化
//状态机
for(int i = 2; i <= n; i ++){
f[i] = Math.max(f[i - 1], f[i - 2] + w[i]);
}
System.out.println(f[n]);//要比较两种情况的最大值
}
}
}
1057. 股票买卖 IV - AcWing题库
初始化有两种情况,一种是状态合法:初始化为0,另一种是状态不合法:初始化为负无穷(求最大值)或初始化为正无穷(求最小值)
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int N = 100010;
int M = 110;
int[] w = new int[N];
int[][] f = new int[M][2];//f[i][j][0]前i天,完成了j次交易,手中无货
//f[i][j][1]前i天,正在进行第j次交易,手中有货
for(int i = 0; i <= k; i ++){
Arrays.fill(f[i], -0x3f3f3f3f);
}//f[i][0][1]前i天,一次也不交易(也不在交易进行中),手中有货的情况肯定是不存在的
f[0][0] = 0;//f[i][0][0]前i天,一次也不交易,手中无货,收益为0
for(int i = 1; i <= n; i ++){
w[i] = sc.nextInt();
}
//状态机
for(int i = 1; i <= n; i ++){
for(int j = k; j >= 1; j --){
f[j][0] = Math.max(f[j][0], f[j][1] + w[i]);
f[j][1] = Math.max(f[j - 1][0] - w[i], f[j][1]);
}
}
//遍历,找到最大的情况,因为不一定是进行完k次交易的收益最大
int res = 0;
for(int i = 0; i <= k; i ++){
res = Math.max(res, f[i][0]);//最后的状态一定是手中无货(因为最优解只能是在手中无货的状态中出现,所以就省去了讨论手中有货的情况)
}
System.out.print(res);
}
}
1058. 股票买卖 V - AcWing题库
这道题与前面两道题不同的是,这道题有三个状态。前面两道题只有两个状态。
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int N = 100010;
int[][] f = new int[N][3];
int[] w = new int[N];
int n = sc.nextInt();
f[0][1] = f[0][0] = -0x3f3f3f3f;//不合法状态(不是入口)初始化为负无穷
f[0][2] = 0;//合法状态(入口)初始化为0
for(int i = 1; i <= n; i ++){//录入数据
w[i] = sc.nextInt();
}
//状态机
for(int i = 1; i <= n; i ++){
f[i][0] = Math.max(f[i - 1][0], f[i - 1][2] - w[i]);
f[i][1] = f[i - 1][0] + w[i];
f[i][2] = Math.max(f[i - 1][2], f[i - 1][1]);
}
//有两个出口
System.out.print(Math.max(f[n][1], f[n][2]));
}
}
1052. 设计密码 - AcWing题库
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 这是我看过讲kmp算法讲得最清晰的一个了!!!!!!
还没搞懂,下次再看