第一题:P1004 [NOIP2000 提高组] 方格取数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
package 蓝桥算法训练__提高组.Day3;
import java.io.*;
/**
* @author snippet
* @data 2023-02-07 to 2023-02-22
* P1004 [NOIP2000 提高组] 方格取数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
*/
// 动态规划
// 四维dp板子
public class T1 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
static int n;// n表示方格图的长和宽
static int N = 11;
static int[][] arr = new int[N][N];// 二维数组arr存方格图上i,j位置的值
static int[][][][] dp = new int[N][N][N][N];// 四维数组dp前两个表示第一个同学的行走路径 后两个表示第二个同学的行走路径
static void solve() throws IOException {
n = nextInt();
while (true) {
int a = nextInt();
int b = nextInt();
int c = nextInt();
if (a == 0 && b == 0 && c == 0) {
break;
}
arr[a][b] = c;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
for (int i2 = 1; i2 <= n; i2++) {
for (int j2 = 1; j2 <= n; j2++) {
// dp的状态转移
// 两个同学行走有四种情况
// 1.一起往下走
// 2.一起往右走
// 3.同学1往下走 && 同学2往右走
// 4.同学1往右走 && 同学2往下走
dp[i][j][i2][j2] = Math.max(Math.max(dp[i-1][j][i2-1][j2], dp[i][j-1][i2][j2-1]), Math.max(dp[i-1][j][i2][j2-1], dp[i][j-1][i2-1][j2])) + arr[i][j] + arr[i2][j2];
// 如果两个同学从同一位置走过来 则需要减去一份上一个位置的值
if (i == i2 && j == j2) {
dp[i][j][i2][j2] -= arr[i][j];
}
}
}
}
}
pw.println(dp[n][n][n][n]);
}
public static void main(String[] args) throws IOException {
int t = 1;
while (t-- > 0) {
solve();
}
pw.flush();
}
static int nextInt() throws IOException {
st.nextToken();
return (int)st.nval;
}
}

第三题:P1063 [NOIP2006 提高组] 能量项链 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
package 蓝桥算法训练__提高组.Day3;
import java.io.*;
/**
* @author snippet
* @data 2023-02-07 to 2023-02-22
* P1063 [NOIP2006 提高组] 能量项链 - 洛谷 |
*/
// 区间dp
public class T3 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
static int n,ans;// n表示珠子的个数 ans表示最大能量值
static int N = 220;
static int[] arr = new int[N];// 一维数组arr存每个珠子的能量值 因为是环状 需要开2倍空间存数据
static int[][] dp = new int[N][N];// 二维数组dp存i-(j-1)的最大能量值 因为[s-e]的能量值 = arr[s]*arr[s+1]*arr[e];
// 例如: 2 3 5 10 2 3 5 10
// max = 10*2*3 + 10*3*5 + 10*5*10 = 710
static void solve() throws IOException {
n = nextInt();
for (int i = 1; i <= n; i++) {
arr[i] = nextInt();
arr[i+n] = arr[i];
}
for (int len = 2; len <= n; len++) {// 枚举长度
// 注意这里的开头和结尾的枚举
for (int s = 1; s+len <= 2*n; s++) {// 枚举开头
int end = s+len;// 枚举结尾
for (int k = s+1; k < end; k++) {// 注意区间的划分
// 注意dp的状态转移式
dp[s][end] = Math.max(dp[s][end], dp[s][k]+dp[k][end]+arr[s]*arr[k]*arr[end]);
pw.println(dp[s][end] + " " + arr[s] + " " + arr[k] + " " + arr[end]);
}
pw.println();
}
}
for (int s = 1; s <= n; s++) {
ans = Math.max(ans, dp[s][s+n]);
}
pw.println(ans);
}
public static void main(String[] args) throws IOException {
int t = 1;
while (t-- > 0) {
solve();
}
pw.flush();
}
static int nextInt() throws IOException {
st.nextToken();
return (int)st.nval;
}
}
