首页 > 试题广场 >

堆砖块

[编程题]堆砖块
  • 热度指数:3220 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
小易有n块砖块,每一块砖块有一个高度。小易希望利用这些砖块堆砌两座相同高度的塔。为了让问题简单,砖块堆砌就是简单的高度相加,某一块砖只能使用在一座塔中一次。小易现在让能够堆砌出来的两座塔的高度尽量高,小易能否完成呢。

输入描述:
输入包括两行: 第一行为整数n(1 ≤ n ≤ 50),即一共有n块砖块 第二行为n个整数,表示每一块砖块的高度height[i] (1 ≤ height[i] ≤ 500000)


输出描述:
如果小易能堆砌出两座高度相同的塔,输出最高能拼凑的高度,如果不能则输出-1. 保证答案不大于500000。
示例1

输入

3 2 3 5

输出

5

@JacobGo!@minnnng@chorus 这三位的状态转移表述都是错的,虽然本题中不影响结果,但是不利于理解。

以下是正确表述

dp[j]表示B-A+sum为j时,B堆的最大高度

所以把砖块放在B堆时:dp1[j]=dp0[j-h]+h

A堆:dp1[j]=dp0[j+h]

不放:dp1[j]=dp0[j]

这才是正确状态转移,三位互相借鉴的时候就不能仔细看一遍??

自己的代码分明是将A-B+sum作为j,为何注释里要说成B-A+sum,误人子弟。

以下是我的代码

import java.util.Arrays; 
import java.util.Scanner; 
public class Main{ public static void main(String[] args) {
    Scanner scan=new Scanner(System.in); 
    int n=scan.nextInt(); 
    int[] heights=new int[n]; 
    int count=0; 
    for(int i=0;i;i++){
        heights[i]=scan.nextInt(); 
        count+=heights[i]; 
    } 
    int[] dp1=new int[2*count+1]; 
    int[] dp0=new int[2*count+1]; 
    for(int i=0;i2*count+1;i++){
        dp0[i]=-1; 
    }
    dp0[count]=0; 
    for(int i=1;i1;i++){ 
         int height=heights[i-1]; 
         for(int j=0;j2*count+1;j++){
             dp1[j]=dp0[j]; 
             if(j-height>=0&&dp0[j-height]!=-1){
                 dp1[j]=Math.max(dp1[j],dp0[j-height]+height); 
             }             
             if(j+height2*count&&dp0[j+height]!=-1){
                 dp1[j]=Math.max(dp1[j],dp0[j+height]); 
             }
         } 
         for(int j=0;j2*count+1;j++){
             dp0[j]=dp1[j]; 
         }
     } 
     int max=-1; 
     for(int i=1;i1;i++){
        max=Math.max(max,dp0[count]); 
     }
     System.out.println(max==0?-1:max); 
     }
}
编辑于 2018-04-06 21:14:24 回复(0)
/*
                 动态规划解决。(用砖堆两个塔,A塔和B塔,B塔-A塔高度差为: -sumHeight~sumHeight,防止数组下表越界,加上sumHeight)。

	 dp[i][j]表示使用前 i 块砖,B-A 塔高度差为 j 时 B 塔的最大高度。  则解为  dp[n][0].使用滚动数组方法解决当 n 过大时 dp[n+1][2*sumHeight+1]二维数组占用内存过高问题,状态转移方程为:

	  					dp[i-1][j], 第 i 块砖不用

	 dp[i][j] =  max    dp[i-1][j-height[i]], 第 i 块砖放在 A 塔

	   					dp[i-1][j+height[i]] + height[i], 第 i 块砖放在 B 塔


	


	*/
import java.util.*;
public class PileOfBricks {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scan = new Scanner(System.in);
		while(scan.hasNext()){
			int n = scan.nextInt();
			int[] height = new int[n+1];
			int sumHeight = 0;
			for(int i=1; i<=n ;i++){
				height[i] = scan.nextInt();
				sumHeight += height[i];
			}
			
			int[][] dp = new int[2][2*sumHeight+1];
			
			for(int i=0; i<2*sumHeight+1; i++)
				dp[0][i] = -1;
			
			dp[0][sumHeight] = 0;
			
			for(int i=1; i<=n; i++){
				for(int j=0; j<2*sumHeight+1; j++){
					dp[1][j] = dp[0][j];
					if(j-height[i]>=0 && dp[0][j-height[i]]!=-1)
						dp[1][j] = Math.max(dp[1][j], dp[0][j-height[i]]);
					if(j+height[i]<=2*sumHeight && dp[0][j+height[i]]!=-1)
						dp[1][j] = Math.max(dp[1][j], dp[0][j+height[i]]+height[i]);
				}
				int[] temp = dp[0];
				dp[0] = dp[1];
				dp[1] = temp;
			}
			if(dp[0][sumHeight] == 0)
				System.out.println(-1);
			else
				System.out.println(dp[0][sumHeight]);
		}
	}

}



编辑于 2017-08-01 11:14:51 回复(0)