多米诺骨牌问题

现有n块”多米诺骨牌”s1,s2,s3,…sn水平放成一排,每次骨牌si包含左右两个部分,每个部分赋予一个非负整数值,如下图所示为包含6块骨牌的序列.骨牌可做180度旋转,使得原来在左边的值变到右边,而原来右边的值移到左边,假设不论si如何旋转,L[i]总是存储si左边的值, R[i]总是存储si右边的值, W[i]用于存储si的状态:当L[i]<=R[i]时记为0,否则记为1,试采用动态规划算法设计时间复杂度为o(n)的算法

在这里插入图片描述
参考博客:https://blog.csdn.net/duguduchong/article/details/6004451

在这里插入图片描述

//将其翻写成java
public class DominoTest {
	public static void main(String[] args) {
		// int[][] domino = {{5,8},{4,2},{9,6},{7,7},{3,9},{11,10}};
		int[] L = {5, 4, 9, 7, 3, 11};
		int[] R = {8, 2, 6, 7, 9, 10};
		int[] status = new int[L.length];
		System.out.println("最大值为:" + Domino(L, R, status));
	}

	public static int Domino(int[] L, int[] R, int[] status) {
		int max = 0; //定义返回值,即最大值
		int[][] dp = new int[2][L.length];//定义动态二维数组存储乘积的中间值
		int[][] dpstatus = new int[2][L.length];//定义动态二维数组存储中间转换状态,状态表示是否调换顺序
		//一次循环动态求出中间最大值
		for (int i = 0; i < dp[0].length - 1; i++) {
			int La = L[i];
			int Rb = R[i];
			int LA = L[i + 1];
			int RB = R[i + 1];
			if ((dp[0][i] + Rb * LA) > (dp[1][i] + La * LA)) {
				dp[0][i + 1] += dp[0][i] + Rb * LA;
				dpstatus[0][i + 1] = 0;
			} else {
				dp[0][i + 1] += dp[1][i] + La * LA;
				dpstatus[0][i + 1] = 1;
			}

			if ((dp[0][i] + Rb * RB) > (dp[1][i] + La * RB)) {
				dp[1][i + 1] += dp[0][i] + Rb * RB;
				dpstatus[1][i + 1] = 0;
			} else {
				dp[1][i + 1] += dp[1][i] + La * RB;
				dpstatus[1][i + 1] = 1;
			}
		}
		System.out.println("动态数组为:" + Arrays.deepToString(dp));
		System.out.println("动态状态中间值为:" + Arrays.deepToString(dpstatus));
		//获取最终的最大值
		if (dp[0][L.length - 1] > dp[1][L.length - 1]) {
			status[L.length - 1] = 0;
			max = dp[0][L.length - 1];
		} else {
			status[L.length - 1] = 1;
			max = dp[1][L.length - 1];
		}
		//取出最终的转换状态
		for (int i = L.length - 1; i > 0; i--) {
			status[i - 1] = (status[i] == 0) ? dpstatus[0][i] : dpstatus[1][i];
		}
		System.out.println("转换状态为:" + Arrays.toString(status));
		return max;
	}
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 点我我会动 设计师:白松林 返回首页