project euler 67

Problem 67


Maximum path sum II

By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.

3
7 4
4 6
8 5  9 3

That is, 3 + 7 + 4 + 9 = 23.

Find the maximum total from top to bottom in triangle.txt(right click and ‘Save Link/Target As…’), a 15K text file containing a triangle with one-hundred rows.

NOTE: This is a much more difficult version of Problem 18. It is not possible to try every route to solve this problem, as there are 299 altogether! If you could check one trillion (1012) routes every second it would take over twenty billion years to check them all. There is an efficient algorithm to solve it. ;o)


最大路径和 II

从下面展示的三角形的顶端出发,不断移动到在下一行与其相邻的元素,能够得到的最大路径和是23。

3
7 4
4 6
8 5  9 3

如上图,最大路径和为 3 + 7 + 4 + 9 = 23。

在这个15K的文本文件triangle.txt(右击并选择“目标另存为……”)中包含了一个一百行的三角形,求从其顶端出发到达底部,所能够得到的最大路径和。

注意:这是第18题的强化版。由于总路径一共有299条,穷举每条路经来解决这个问题是不可能的!即使你每秒钟能够检查一万亿(1012)条路径,全部检查完也需要两千万年。存在一个非常高效的算法能解决这个问题。;o)

package cuppics;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class Prj67 {

	/**
	 * By starting at the top of the triangle below and moving to adjacent
	 * numbers on the row below, the maximum total from top to bottom is 23.
	 * 
	 * 3 7 4 2 4 6 8 5 9 3
	 * 
	 * That is, 3 + 7 + 4 + 9 = 23.
	 * 
	 * Find the maximum total from top to bottom of the triangle below:
	 * 
	 * 75 95 64 17 47 82 18 35 87 10 20 04 82 47 65 19 01 23 75 03 34 88 02 77
	 * 73 07 63 67 99 65 04 28 06 16 70 92 41 41 26 56 83 40 80 70 33 41 48 72
	 * 33 47 32 37 16 94 29 53 71 44 65 25 43 91 52 97 51 14 70 11 33 28 77 73
	 * 17 78 39 68 17 57 91 71 52 38 17 14 91 43 58 50 27 29 48 63 66 04 68 89
	 * 53 67 30 73 16 69 87 40 31 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
	 * @throws IOException 
	 */
	@Test
	public void test() throws IOException {
		List<int[]> dataList = Calculator.readData("D:\\workSpace\\java\\cuppics\\src\\test\\java\\cuppics\\Prj67_data.txt"); 
		Calculator.calculate(dataList, 100);
	}

	public static class Calculator {

		public enum Direction {
			Down, DownLeft, DownRight
		}
		
		public static String directionStr( Direction dir){
			if( dir.equals( Direction.Down)){
				return "↓";
			}else if ( dir.equals( Direction.DownLeft)){
				return "↙";
			}else if( dir.equals( Direction.DownRight)){
				return "↘";
			}
			
			return "==";
		}

		public static List<int[]> readData(String path) throws IOException {

			BufferedReader reader = new BufferedReader(new InputStreamReader(
					new FileInputStream(new File(path))));

			String str = null;
			List<int[]> ret = new ArrayList<int[]>();
			while ((str = reader.readLine()) != null) {
				String[] dataStr = str.split(" ");
				int[] data = new int[dataStr.length];
				for (int i = 0; i < dataStr.length; i++) {
					data[i] = Integer.parseInt(dataStr[i]);
				}
				ret.add(data);
			}
			reader.close();
			return ret;

		}

		public static void calculate(List<int[]> dataList, int lastDataLen) {

			String[] traceStr = new String[lastDataLen];
			String[] traceStrCopy = new String[lastDataLen];
			
			
			int [] maxSumCopy = new int[ lastDataLen];
			int [] maxSum = new int[ lastDataLen];
			
			for (int i = 0; i < traceStr.length; i++) {
				traceStr[i] = "";
				traceStrCopy[i] = "";
				maxSum[0] = dataList.get(0)[0];
			}
						
			for (int i = 1; i < dataList.size(); i++) {
				int[] upData = dataList.get(i - 1);
				int[] data = dataList.get(i);
				
				copyArrays( maxSumCopy, maxSum );
				
				for (int j = 0; j < data.length;  j++) {
					int id = calculateMaxSum(j, upData, data[j], maxSumCopy, maxSum);
					markMax(j, id, traceStrCopy, traceStr);
				}
				traceStrCopy = copyStrs( traceStr);
			}
			
			
			for( int i =  0; i < lastDataLen; i ++){
				System.out.println( traceStr[i]);
			}
			
			int maxId = 0;
			int maxVal = 0;
			for( int i =  0; i < lastDataLen; i ++){
				if( maxSum[i] > maxVal){
					maxVal = maxSum[i];
					maxId = i;
				}
			}
			
			System.out.println("maxId=" + maxId + ", val=" + maxVal);

		}

		private static String[] copyStrs( String[] traceStr) {
			
			String []traceStrCopy = new String[ traceStr.length];
			for( int i =  0; i < traceStr.length ; i ++){
				traceStrCopy[i] = new String(traceStr[i]);
			}
			
			return  traceStrCopy;
			
		}

		private static void copyArrays(int[] maxSumCopy, int[] maxSum) {
			for( int i = 0 ; i < maxSum.length ; i ++){
				maxSumCopy[i] = maxSum[i];
			}
		}

		private static Direction markMax(int currentIndex, int upId, String[] traceStrCopy, String[] traceStr) {
			
			Direction dir = null;
			
			if (upId > currentIndex) {
				dir = Direction.DownLeft;
			} else if (upId == currentIndex) {
				dir = Direction.Down;
			} else {
				dir = Direction.DownRight;
			}
			
			traceStr[currentIndex] = traceStrCopy[upId] + directionStr(dir);
			
			return dir;
		}

		private static int calculateMaxSum(int jId, int[] upData, int val, int[] maxSumCopy, int [] maxSum) {

			int maxVal = 0;
			int maxId = 0;
			for (int i = Math.max(0, jId - 1); i <= Math.min(jId,
					upData.length + 1); i++) {
				if (val + maxSumCopy[i] > maxVal) {
					maxVal = val + maxSumCopy[i];
					maxId = i;
				}
			}
			maxSum[jId] = maxSumCopy[maxId] + val; 
			return maxId;
		}

	}

}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值