蓝桥算法训练__提高组.Day3

第一题: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;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值