LeetCode1049. 最后一块石头的重量 II
/**
* 思路:让石头分成重量相同的两堆,相撞之后剩下的石头最小
* @param stones
* @return
*/
public int lastStoneWeightII(int[] stones) {
int sum=0,n=stones.length,subsum=0;
for(int i=0;i<n;i++) {
sum+=stones[i];
}
subsum=sum;
sum=sum/2;
//初始化
int[][] dp = new int[n+1][sum+1];
for(int i=1;i<=sum;i++) {
if(stones[0]<=i) dp[1][i]=stones[0];
}
//背包
for(int i=1;i<=n;i++) {
for(int j=1;j<=sum;j++) {
if(stones[i-1]>j) dp[i][j]=dp[i-1][j];
else dp[i][j]=Math.max(dp[i-1][j], dp[i-1][j-stones[i-1]]+stones[i-1]);
}
}
return Math.abs(subsum-dp[n][sum]-dp[n][sum]);
}
LeetCode494. 目标和
/**
* dp数组的含义:刚好能凑到总和为j的最多种方案
* @param nums
* @param target
* @return
*/
public int findTargetSumWays(int[] nums, int target) {
int sum=0,n=nums.length,left=0;
for(int i=0;i<n;i++) {
sum+=nums[i];
}
//保证target要小于sum,才能凑到
if(sum < Math.abs(target))return 0;
//保证可以凑到target值,left=(sum+target)/2
if((sum+target)%2==1)return 0;
left=(sum+target)/2;
//初始化
int[][] dp = new int[n+1][left+1];
//初始化最顶列-》只有恰好等于那个数字的位置,才可以赋值
if (nums[0] <= left) {
dp[1][nums[0]] = 1;
}
//初始化最左列,这时总分数为0,如果存在0的话,便有指数(2的count0次)种方法
int count0=0;
dp[0][0]=1;
for(int i=1;i<=n;i++) {
if(nums[i-1]==0) {
count0++;
}
dp[i][0]=(int)Math.pow(2, count0);
}
//背包
for(int i=1;i<=n;i++) {
for(int j=1;j<=left;j++) {
if(nums[i-1]>j) dp[i][j]=dp[i-1][j];
else dp[i][j]=dp[i-1][j]+dp[i-1][j-nums[i-1]];
}
}
return dp[n][left];
}
LeetCode474.一和零
public int findMaxForm(String[] strs, int m, int n) {
int k=strs.length;
int [][][] dp = new int[k+1][m+1][n+1];
for(int i=1;i<=k;i++) {
int[] res = find(strs[i-1]);
int res0=res[0];
int res1=res[1];
for(int j=0;j<=m;j++) {
for(int z=0;z<=n;z++) {
if(res0<=j&&res1<=z) dp[i][j][z]=Math.max(dp[i-1][j][z], dp[i-1][j-res0][z-res1]+1);
else dp[i][j][z]=dp[i-1][j][z];
}
}
}
return dp[k][m][n];
}
public int[] find(String str) {
int [] res = new int[2];
for(int i=0;i<str.length();i++) {
res[str.charAt(i)-'0']++;
}
return res;
}