题目
分析
代码
package com.graph;
import java.util.*;
public class Solution{
int sum=0;
int count=0;
int tar;
int[] as;
int n;
//方法一:树的遍历,剪枝
//递归
public void solve(int[] as, int tar){
this.tar = tar;
this.as = as;
if(as==null || as.length==0)
System.out.println(count);
n = as.length;
handle(0);
System.out.println(count);
}
public void handle(int i){
if(i==n){
if(sum==tar)
count++;
return;
}
//减枝
//当剩余数的最大和最小无法满足要求时,返回
int tmpSum = getSum(i);
if(sum-tmpSum>tar || sum+tmpSum<tar){
return;
}
//将i设为+号,其实就是preOrder遍历
//遍历+号边
sum = sum+as[i];
handle(i+1);
sum = sum-as[i];
//遍历-号边
sum = sum-as[i];
handle(i+1);
sum = sum+as[i];
}
//可优化,变成一个数组存着,然后取用
public int getSum(int k){
int tmpSum = 0;
for(int i=k; i<n; i++){
tmpSum+=as[i];
}
return tmpSum;
}
//方法二:动态规划
public void solve_dp(int[] as, int tar){
this.tar = tar;
this.as = as;
if(as==null || as.length==0)
return;
n = as.length;
int tmpSum = getSum(n);
if(tmpSum<Math.abs(tar))
return;
int dSum = tmpSum<<1;
int[][] dp = new int[n][dSum+1];
if(as[0]==0) {
dp[0][tmpSum] = 2;
}else {
dp[0][sum-as[0]] = 1;
dp[0][sum+as[0]] = 1;
}
for(int i=0; i<n; i++) {
for(int j=0; j<dSum+1; j++) {
if(j-as[i]>=0) {
dp[i][j]+=dp[i-1][j-as[i]];
}
if(j+as[i]<=dSum) {
dp[i][j]+=dp[i-1][j+as[i]];
}
}
}
count = dp[n-1][tar+sum];
System.out.println(count);
}
public static void main(String[] args) {
Solution s = new Solution();
s.solve(new int[] {1,1,1,1,1}, 3);
}
}