2.18 数组分割

2.18 数组分割

基础问题:有一个没有排序的,元素个数为2n的正整数数组,要去:如何能把这个数组分割成为元素个数为n的两个数组,并且使两个子数组的和最接近

解法:

  • 解法 1 : 动态规划
    • 状态定义:boolean dp[i][j] 表示数组从下表0开始到下表i区间范围内选取若干个正整数,是否存在一种选取方法使得被选取的这些正整数的和等于j。
    • 状态转移方程 :
      dp[i][j] = {
      dp[i-1][j] | dp[i-1][j-nums[i]] , if j >= nums[i]
      dp[]i-1][j] , if j < nums[i]
      }
    • 初始状态:
      boolean dp[i][j] = false , for all i && all j
      dp[i][0] = true , for all i , 表示不选取任何整数,则被选取的整数的和为0
      dp[0][nums[0]] = true , 表示当i==0的时候,只有一个正整数可以被选取,因此dp[0][nums[0]] = true

拓展问题:如果数组中有负数怎么办?

all coding

// 2.18 数组分割
class Test{
	public static void main(String[] args) {
		/**
		基础问题:有一个没有排序的,元素个数为2n的正整数数组,要去:如何能把这个数组分割成为元素个数为n的两个数组,并且使两个子数组的和最接近
		> 解法:
			- 解法 1 : 动态规划
				状态定义:
					boolean dp[i][j] 表示数组从下表0开始到下表i区间范围内选取若干个正整数,是否存在一种选取方法使得被选取的这些正整数的和等于j。
				状态转移方程 : 
					dp[i][j] = {
						dp[i-1][j] | dp[i-1][j-nums[i]] , if j >= nums[i]
						dp[]i-1][j] , if j < nums[i]

					}
				初始状态:
					boolean dp[i][j] = false , for all i && all j
					dp[i][0] = true , for all i , 表示不选取任何整数,则被选取的整数的和为0
					dp[0][nums[0]] = true , 表示当i==0的时候,只有一个正整数可以被选取,因此dp[0][nums[0]] = true 

		*/
		int[] arr = new int[]{1,5,11,5};
		int[] arr2 = new int[]{1,2,3,5};
		System.out.println(canPartition(arr));
	}
	public static void print(boolean[][] arr){
		for(boolean[] ar:arr){
			for(boolean a:ar){
				System.out.print(a+" ");
			}
			System.out.println();
		}
	}

	public static boolean canPartition(int[] nums){
		int n = nums.length;
		if(n<2) return false;
		int sum = 0;
		int maxNum = 0;
		for(int num:nums){
			sum+=num;
			maxNum = Math.max(maxNum,num);
		}
		if(sum%2 != 0) return false;
		int target = sum/2;
		if(maxNum > target) return false;
		boolean[][] dp = new boolean[n][target+1];
		for(int i = 0;i<n;i++) dp[i][0] = true;
		dp[0][nums[0]] = true;
		for(int i=1;i<n;i++){
			int num = nums[i];
			for(int j =1;j<=target;j++){
				if( j>= num) dp[i][j] = dp[i-1][j] | dp[i-1][j-num];
				else dp[i][j] = dp[i-1][j];
			}
		}
		print(dp);
		return dp[n-1][target];
	}
	/**
	拓展问题:
		如果数组中有负数怎么办?
	*/
}
posted @ 2020-11-25 14:23  BOTAK  阅读(90)  评论(0编辑  收藏  举报