class Solution {
public int numTrees(int n) {
int[] dp = new int[n+1];
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i <= n ; i++){
for(int j = 1; j<=i ;j++){
dp[i] += dp[j-1] * dp[i-j];
}
}
return dp[n];
}
}
class Solution {
public boolean canPartition(int[] nums) {
int sum = 0;
for(int num : nums){
sum += num;
}
if(sum % 2 != 0 ){
return false; //奇数不行
}
int target = sum / 2;
int[] dp = new int[target +1];
for(int i = 0 ; i < nums.length ; i++){
for(int j = target ; j >= nums[i] ;j--){
dp[j] = Math.max(dp[j], dp[j-nums[i]] + nums[i]);
}
if(dp[target] == target) return true;
}
return dp[target] == target;
}
}
class Solution {
public int lastStoneWeightII(int[] stones) {
int sum = 0;
for(int num : stones){
sum += num;
}
int target = sum / 2;
int[] dp = new int[target +1];
for(int i = 0 ; i < stones.length ; i++){
for(int j = target ; j >= stones[i] ;j--){
dp[j] = Math.max(dp[j], dp[j-stones[i]] + stones[i]);
}
}
return sum - 2*dp[target];
}
}