javaFX 实现 最大总和问题

本文介绍了如何使用JavaFX解决最大总和问题,通过动态规划的算法思想,自顶向下进行递推求解,最终得出最优解。文章提供了解决问题的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

将正整数排成等边三角形(也叫数塔),三角形的底边有个数,下图给出了的一个例
子。从三角形顶点出发通过一系列相邻整数(在图中用正方形表示),如何使得到达底边
时的总和最大?

算法思想

动态规划
自顶向下应用递推式F[i][j] = num[i][j] + max(F[i+1][j], F[i+1][j+1])一级一级向下求解。

结果

在这里插入图片描述

代码

package CourseDesign;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.util.Arrays;

public class B2 extends Application {
    long sleep = 0;

    @Override
    public void start(Stage primaryStage) throws Exception {
        // 初始化画布
        GridPane gridPane = new GridPane();
        gridPane.setMinSize(300, 200);
        gridPane.setAlignment(Pos.CENTER);
        gridPane.setPadding(new Insets(10));
        gridPane.setVgap(15);
        gridPane.setHgap(20);

        paintNumes(gridPane);

        // 建立线程开始计算
        Thread thread = new Thread(() -> {
            int[][] numes = getNumes();// 得到处理的数塔
            int max = getMax_V(gridPane, numes, 0, 0, true);// 返回计算结果
            Text text1 = new Text("最大值:" + max);// 输出到界面
            text1.setFont(Font.font(30));
            Runnable runnable = () -> {
                gridPane.add(text1, 2*numes.length - 1, 1 + numes.length);// 新建线程输出到界面
            };
            Platform.runLater(runnable);
        });
        thread.setDaemon(true);// 设置线程属性
        thread.start();

        primaryStage.setScene(new Scene(gridPane));
        primaryStage.show();
    }

    // 将原始数塔画出来
    private void paintNumes(GridPane gridPane) {
        int[][] numes = getNumes();
        int l = numes.length - 1;
        for (int i = 0; i < numes.length; i++) {
            int t = l--;
            for (int j = 0; j <= i; j++) {
                gridPane.add(getText(numes[i][j]), t, i);
                t += 2;
            }
        }
    }

    // 返回预定义的数组
    private int[][] getNumes() {
        int[][] numes = new int[5][5];
        int[] n = {9, 12, 15, 10, 6, 8, 2, 18, 9, 5, 19, 7, 10, 4, 16};
        int p = 0;
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j <= i; j++) {
                numes[i][j] = n[p++];
            }
        }
        return numes;
    }
    // 测试用
    private static int[][] getNumes1() {
        int[][] numes = new int[5][5];
        int[] n = {9, 12, 15, 10, 6, 8, 2, 18, 9, 5, 19, 7, 10, 4, 16};
        int p = 0;
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j <= i; j++) {
                numes[i][j] = n[p++];
            }
        }
        return numes;
    }

    // 返回一个带有指定数字k的Text标签
    private Text getText(int k) {
        Text text = new Text(Integer.toString(k));
        text.setFont(Font.font(30));
        text.setFill(Color.GREEN);
        return text;
    }



    /**
     * // 画图动态显示计算
     * @param gridPane 面板
     * @param nums 数塔
     * @param row 行
     * @param column 列
     * @param biger 是否是较大值
     * @return 从当前节点走到数塔底部的最大值
     */
    public synchronized int getMax_V(GridPane gridPane, int[][] nums, int row, int column, boolean biger) {
        setColor(gridPane, nums, row, column, Color.RED);// 先画红色

        if (row == nums.length - 1) {// 到数塔底部
            if (!biger) {
                setColor(gridPane, nums, row, column, Color.GREEN);// 不是较大值用绿色
            }
            return nums[row][column];
        }

        int l = getMax(nums, row + 1, column);// 预处理左子树
        int r = getMax(nums, row + 1, column + 1);// 预处理右子树
        int max = nums[row][column] + Math.max(getMax_V(gridPane, nums, row + 1, column, l > r), getMax_V(gridPane, nums, row + 1, column + 1, r > l));
        if (!biger) {//不是最大值,画回绿色
            setColor(gridPane, nums, row, column, Color.GREEN);
        }

        return max;
    }

    // 通过节点位置给节点画指定颜色
    private void setColor(GridPane gridPane, int[][] nums, int row, int column, Color color) {
        try {
            sleep = 600;
            Thread.sleep(sleep);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Runnable runnable = () -> {
            Text text = getText(nums[row][column]);
            text.setFill(color);
            gridPane.add(text, (nums[0].length - 1) - row + column * 2, row);
        };
        Platform.runLater(runnable);
    }

    // 预处理函数得到指定节点到数塔底部的最大值
    public static int getMax(int[][] nums, int row, int column) {
        if (row == nums.length - 1)
            return nums[row][column];
        return nums[row][column] + Math.max(getMax(nums, row + 1, column), getMax(nums, row + 1, column + 1));
    }

    public static void main(String[] args) {
        launch(args);
//        System.out.println(getMax(getNumes1(), 0, 0));
    }
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值