parent
e39312c69a
commit
5a1607a02a
@ -0,0 +1,58 @@
|
||||
package zuolaos.jichuban;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Code19_暴力递归 {
|
||||
}
|
||||
|
||||
|
||||
class 移动圆盘 {
|
||||
public void process(int N, String from, String to, String other) {
|
||||
if (N == 1) {
|
||||
System.out.println("move " + "1" + " form " + from + " to " + to);
|
||||
return;
|
||||
}
|
||||
|
||||
process(N - 1, from, other, to);
|
||||
System.out.println("move " + N + " form " + from + " to " + to);
|
||||
process(N - 1, other, to, from);
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new 移动圆盘().process(3, "from", "to", "other");
|
||||
}
|
||||
}
|
||||
|
||||
class 字符串全部子序列 {
|
||||
public void process(char[] str, int index, String path, List<String> ans) {
|
||||
if (index == str.length) {
|
||||
ans.add(path);
|
||||
return;
|
||||
}
|
||||
process(str, index + 1, path, ans);
|
||||
process(str, index + 1, path + str[index], ans);
|
||||
}
|
||||
}
|
||||
|
||||
class 字符串不同排列 {
|
||||
|
||||
public void process(char[] str, int index, List<String> ans) {
|
||||
if (index == str.length) {
|
||||
ans.add(String.valueOf(str));
|
||||
return;
|
||||
}
|
||||
for (int i = index; i < str.length; i++) {
|
||||
//index 和后面的交换
|
||||
process(str, i, ans);
|
||||
//index 和后面的交换回来 恢复现场
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,845 @@
|
||||
package zuolaos.jichuban;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Code20_动态规划 {
|
||||
}
|
||||
|
||||
class 机器人到达指定位置 {
|
||||
|
||||
public int process1(int cur, int rest, int aim, int N) {
|
||||
if (rest == 0) {
|
||||
return cur == aim ? 1 : 0;
|
||||
}
|
||||
if (cur == 1) {
|
||||
return process1(2, rest - 1, aim, N);
|
||||
}
|
||||
if (cur == N) {
|
||||
return process1(N - 1, rest - 1, aim, N);
|
||||
}
|
||||
return process1(cur + 1, rest - 1, aim, N) + process1(cur - 1, rest - 1, aim, N);
|
||||
}
|
||||
|
||||
|
||||
public int process2(int cur, int rest, int aim, int N, int[][] dp) {
|
||||
if (dp[cur][rest] != -1) {
|
||||
return dp[cur][rest];
|
||||
}
|
||||
int ans = 0;
|
||||
if (rest == 0) {
|
||||
ans = cur == aim ? 1 : 0;
|
||||
} else if (cur == 1) {
|
||||
ans = process2(2, rest - 1, aim, N, dp);
|
||||
} else if (cur == N) {
|
||||
ans = process2(N - 1, rest - 1, aim, N, dp);
|
||||
} else {
|
||||
ans = process2(cur + 1, rest - 1, aim, N, dp) + process2(cur - 1, rest - 1, aim, N, dp);
|
||||
}
|
||||
dp[cur][rest] = ans;
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
public int process3(int start, int K, int aim, int N) {
|
||||
int[][] dp = new int[N + 1][K + 1];
|
||||
dp[aim][0] = 1;
|
||||
for (int rest = 1; rest < K + 1; rest++) {
|
||||
dp[1][rest] = dp[2][rest - 1];
|
||||
for (int cur = 2; cur < N; cur++) {
|
||||
dp[cur][rest] = dp[cur - 1][rest - 1] + dp[cur + 1][rest - 1];
|
||||
}
|
||||
dp[N][rest] = dp[N - 1][rest - 1];
|
||||
}
|
||||
return dp[start][K];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
机器人到达指定位置 aaa = new 机器人到达指定位置();
|
||||
System.out.println(aaa.process1(2, 4, 4, 6));
|
||||
System.out.println(aaa.process3(2, 4, 4, 6));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class 先后手取牌 {
|
||||
public static void main(String[] args) {
|
||||
先后手取牌 aaa = new 先后手取牌();
|
||||
int[] arr = {10, 20, 30, 40, 50, 600};
|
||||
int R = arr.length;
|
||||
int[][] fdp = new int[R][R];
|
||||
int[][] gdp = new int[R][R];
|
||||
for (int i = 0; i < R; i++) {
|
||||
for (int j = 0; j < R; j++) {
|
||||
fdp[i][j] = -1;
|
||||
gdp[i][j] = -1;
|
||||
}
|
||||
}
|
||||
int f = aaa.f(arr, 0, arr.length - 1, fdp, gdp);
|
||||
int g = aaa.g(arr, 0, arr.length - 1, fdp, gdp);
|
||||
System.out.println(f + "..." + g);
|
||||
System.out.println(aaa.process(arr));
|
||||
}
|
||||
|
||||
public int f(int[] arr, int L, int R, int[][] fdp, int[][] gdp) {
|
||||
if (fdp[L][R] != -1) {
|
||||
return fdp[L][R];
|
||||
}
|
||||
int ans = 0;
|
||||
if (L == R) {
|
||||
ans = arr[L];
|
||||
} else {
|
||||
int p1 = arr[L] + g(arr, L + 1, R, fdp, gdp);
|
||||
int p2 = arr[R] + g(arr, L, R - 1, fdp, gdp);
|
||||
ans = Math.max(p1, p2);
|
||||
}
|
||||
fdp[L][R] = ans;
|
||||
return ans;
|
||||
}
|
||||
|
||||
public int g(int[] arr, int L, int R, int[][] fdp, int[][] gdp) {
|
||||
if (gdp[L][R] != -1) {
|
||||
return gdp[L][R];
|
||||
}
|
||||
int ans = 0;
|
||||
if (L != R) {
|
||||
int p1 = f(arr, L, R - 1, fdp, gdp);
|
||||
int p2 = f(arr, L + 1, R, fdp, gdp);
|
||||
ans = Math.min(p1, p2);
|
||||
|
||||
}
|
||||
gdp[L][R] = ans;
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
public int process(int[] arr) {
|
||||
int N = arr.length;
|
||||
int[][] fdp = new int[N][N];
|
||||
int[][] gdp = new int[N][N];
|
||||
for (int i = 0; i < N; i++) {
|
||||
fdp[i][i] = arr[i];
|
||||
}
|
||||
|
||||
for (int start = 1; start < N; start++) {
|
||||
int L = 0;
|
||||
int R = start;
|
||||
while (R < N) {
|
||||
fdp[L][R] = Math.max(arr[L] + gdp[L + 1][R], arr[R] + gdp[L][R - 1]);
|
||||
gdp[L][R] = Math.min(fdp[L][R - 1], fdp[L + 1][R]);
|
||||
L++;
|
||||
R++;
|
||||
}
|
||||
}
|
||||
return Math.max(fdp[0][N - 1], gdp[0][N - 1]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class 背包问题 {
|
||||
|
||||
public int process(int[] v, int[] w, int index, int bag) {
|
||||
if (bag < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (index == w.length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int p1 = process(v, w, index + 1, bag);
|
||||
int p2 = 0;
|
||||
if (bag < w[index]) {
|
||||
p2 = 0;
|
||||
} else {
|
||||
p2 = process(v, w, index + 1, bag - w[index]) + v[index];
|
||||
}
|
||||
return Math.max(p1, p2);
|
||||
}
|
||||
|
||||
|
||||
public int dp(int[] v, int[] w, int rest) {
|
||||
|
||||
int N = w.length;
|
||||
int[][] dp = new int[N + 1][rest + 1];
|
||||
for (int index = N - 1; index >= 0; index--) {
|
||||
for (int bag = 0; bag < rest; bag++) {
|
||||
int p1 = dp[index + 1][bag];
|
||||
int p2 = bag < w[index] ? 0 : dp[index + 1][bag - w[index]] + v[index];
|
||||
dp[index][rest] = Math.max(p1, p2);
|
||||
}
|
||||
}
|
||||
return dp[0][rest];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class 数字字符转换 {
|
||||
|
||||
public int process(char[] str, int i) {
|
||||
if (i == str.length) {
|
||||
return 1;
|
||||
}
|
||||
if (str[i] == '0') {
|
||||
return 0;
|
||||
}
|
||||
int p1 = process(str, i + 1);
|
||||
if (i + 1 < str.length && (str[i] - '0') * 10 + (str[i + 1] - '0') < 27) {
|
||||
p1 += process(str, i + 2);
|
||||
}
|
||||
return p1;
|
||||
}
|
||||
|
||||
public int dp(char[] str) {
|
||||
int N = str.length;
|
||||
int[] dp = new int[N + 1];
|
||||
dp[N] = 1;
|
||||
for (int i = N - 1; i >= 0; i--) {
|
||||
int ans = 0;
|
||||
if (str[i] != '0') {
|
||||
ans = dp[i + 1];
|
||||
if (i + 1 < str.length && (str[i] - '0') * 10 + (str[i + 1] - '0') < 27) {
|
||||
ans += dp[i + 2];
|
||||
}
|
||||
}
|
||||
dp[i] = ans;
|
||||
}
|
||||
return dp[0];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class 使用贴纸组合形成字符串 {
|
||||
|
||||
public int process1(String target, String[] tiks) {
|
||||
if (target.length() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int min = Integer.MAX_VALUE;
|
||||
for (String first : tiks) {
|
||||
//减少target 字符串的数量
|
||||
String rest = filterStr(target, first);
|
||||
if (rest.length() != target.length()) {
|
||||
min = Math.min(min, process1(rest, tiks));
|
||||
}
|
||||
}
|
||||
if (min == Integer.MAX_VALUE) {
|
||||
return min;
|
||||
} else {
|
||||
return min + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// tiks 表示某个字帖 中具体字符出现的数量
|
||||
public int process2(String target, int[][] tiks) {
|
||||
if (target.length() == 0) {
|
||||
return 0;
|
||||
}
|
||||
char[] chars = target.toCharArray();
|
||||
int[] tcount = new int[26];
|
||||
for (char ch : chars) {
|
||||
tcount[ch - 'a']++;
|
||||
}
|
||||
int min = Integer.MAX_VALUE;
|
||||
for (int[] first : tiks) {
|
||||
//减少target 字符串的数量
|
||||
if (first[chars[0] - 'a'] > 0) {
|
||||
for (int i = 0; i < 26; i++) {
|
||||
if (tcount[i] > 0) {
|
||||
int num = tcount[i] - first[i];
|
||||
StringBuilder rest = new StringBuilder();
|
||||
while (num > 0) {
|
||||
rest.append((char) (i + 'a'));
|
||||
num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
min = Math.min(min, process2("", tiks));
|
||||
}
|
||||
}
|
||||
if (min == Integer.MAX_VALUE) {
|
||||
return min;
|
||||
} else {
|
||||
return min + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// tiks 表示某个字帖 中具体字符出现的数量
|
||||
public int process3(String target, int[][] tiks, Map<String, Integer> dp) {
|
||||
if (dp.containsKey(target)) {
|
||||
return dp.get(target);
|
||||
}
|
||||
if (target.length() == 0) {
|
||||
return 0;
|
||||
}
|
||||
char[] chars = target.toCharArray();
|
||||
int[] tcount = new int[26];
|
||||
for (char ch : chars) {
|
||||
tcount[ch - 'a']++;
|
||||
}
|
||||
int min = Integer.MAX_VALUE;
|
||||
for (int[] first : tiks) {
|
||||
//减少target 字符串的数量
|
||||
if (first[chars[0] - 'a'] > 0) {
|
||||
for (int i = 0; i < 26; i++) {
|
||||
if (tcount[i] > 0) {
|
||||
int num = tcount[i] - first[i];
|
||||
StringBuilder rest = new StringBuilder();
|
||||
while (num > 0) {
|
||||
rest.append((char) (i + 'a'));
|
||||
num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
min = Math.min(min, process2("", tiks));
|
||||
}
|
||||
}
|
||||
min = min + min == Integer.MAX_VALUE ? 0 : 1;
|
||||
dp.put(target, min);
|
||||
return min;
|
||||
}
|
||||
|
||||
|
||||
private String filterStr(String target, String first) {
|
||||
char[] chars1 = target.toCharArray();
|
||||
char[] chars2 = first.toCharArray();
|
||||
int[] count = new int[26];
|
||||
for (char c : chars1) {
|
||||
count[c - 'a']++;
|
||||
}
|
||||
for (char c : chars2) {
|
||||
count[c - 'a']--;
|
||||
}
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < 26; i++) {
|
||||
while (count[i] > 0) {
|
||||
str.append((char) ('a' + i));
|
||||
count[i]--;
|
||||
}
|
||||
}
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class 二维数组最佳路径 {
|
||||
|
||||
public int process(int[][] m) {
|
||||
if (m == null || m.length == 0 || m[0] == null || m[0].length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int row = m.length;
|
||||
int col = m[0].length;
|
||||
int[] dp = new int[col];
|
||||
dp[0] = m[0][0];
|
||||
for (int j = 1; j < col; j++) {
|
||||
dp[j] += dp[j - 1] + m[0][j];
|
||||
}
|
||||
|
||||
for (int i = 1; i < row; i++) {
|
||||
dp[0] += m[i][0];
|
||||
for (int j = 1; j < col; j++) {
|
||||
dp[i] = Math.min(dp[j - 1], dp[j]) + m[i][j];
|
||||
}
|
||||
}
|
||||
return dp[col - 1];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class 数组中组成固定和的方法数 {
|
||||
|
||||
public int process(int[] arr, int index, int rest) {
|
||||
if (rest < 0) {
|
||||
return 0;
|
||||
}
|
||||
if (index == arr.length) {
|
||||
return rest == 0 ? 1 : 0;
|
||||
}
|
||||
//选你
|
||||
int p1 = process(arr, index + 1, rest - arr[index]);
|
||||
//不选你
|
||||
int p2 = process(arr, index + 1, rest);
|
||||
return p1 + p2;
|
||||
}
|
||||
|
||||
public int dp(int[] arr, int aim) {
|
||||
if (aim == 0) {
|
||||
return 1;
|
||||
}
|
||||
int row = arr.length;
|
||||
int col = aim;
|
||||
int[][] dp = new int[row + 1][col + 1];
|
||||
dp[row][0] = 1;
|
||||
for (int index = row - 1; index >= 0; index--) {
|
||||
for (int rest = 0; rest <= aim; rest++) {
|
||||
dp[index][rest] = dp[index + 1][rest] + (rest - arr[index]) >= 0 ? dp[index + 1][rest - arr[index]] : 0;
|
||||
}
|
||||
}
|
||||
return dp[0][aim];
|
||||
}
|
||||
}
|
||||
|
||||
class 数组中组成固定和的方法数可重复选 {
|
||||
public int process(int[] arr, int index, int rest) {
|
||||
if (index == arr.length) {
|
||||
return rest == 0 ? 1 : 0;
|
||||
}
|
||||
int ways = 0;
|
||||
for (int zhang = 0; zhang * arr[index] <= rest; zhang++) {
|
||||
ways += process(arr, index + 1, rest - zhang * arr[index]);
|
||||
}
|
||||
return ways;
|
||||
}
|
||||
|
||||
public int dp(int[] arr, int aim) {
|
||||
if (aim == 0) {
|
||||
return 1;
|
||||
}
|
||||
int N = arr.length;
|
||||
int[][] dp = new int[N + 1][aim + 1];
|
||||
dp[N][0] = 1;
|
||||
for (int index = N - 1; index >= 0; index--) {
|
||||
for (int rest = 0; rest <= aim; rest++) {
|
||||
int ways = 0;
|
||||
for (int zhang = 0; zhang * arr[index] <= rest; zhang++) {
|
||||
ways += dp[index + 1][rest - zhang * arr[index]];
|
||||
}
|
||||
dp[index][rest] = ways;
|
||||
}
|
||||
}
|
||||
return dp[0][aim];
|
||||
}
|
||||
|
||||
|
||||
public int dp2(int[] arr, int aim) {
|
||||
if (aim == 0) {
|
||||
return 1;
|
||||
}
|
||||
int N = arr.length;
|
||||
int[][] dp2 = new int[N + 1][aim + 1];
|
||||
dp2[N][0] = 1;
|
||||
for (int index = N - 1; index >= 0; index--) {
|
||||
for (int rest = 0; rest <= aim; rest++) {
|
||||
dp2[index][rest] = (rest - arr[index]) >= 0 ? dp2[index][rest - arr[index]] : 0 + dp2[index + 1][rest];
|
||||
}
|
||||
}
|
||||
return dp2[0][aim];
|
||||
}
|
||||
}
|
||||
|
||||
class 数组中组成固定和的方法数重复选的个数确定 {
|
||||
|
||||
class Info {
|
||||
public int[] zhangs;
|
||||
public int[] amounts;
|
||||
|
||||
public Info(int[] zhangs, int[] amounts) {
|
||||
this.zhangs = zhangs;
|
||||
this.amounts = amounts;
|
||||
}
|
||||
}
|
||||
|
||||
public int process(int[] arr, int aim) {
|
||||
if (aim == 0) {
|
||||
return 1;
|
||||
}
|
||||
Info info = getInfo(arr);
|
||||
return f(info.amounts, info.zhangs, 0, aim);
|
||||
}
|
||||
|
||||
private int f(int[] amounts, int[] zhangs, int index, int rest) {
|
||||
if (index == zhangs.length) {
|
||||
return rest == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
int ways = 0;
|
||||
for (int zhang = 0; zhang * amounts[index] <= rest && zhang <= zhangs[index]; zhang++) {
|
||||
ways += f(amounts, zhangs, index + 1, rest - zhang * amounts[index]);
|
||||
}
|
||||
return ways;
|
||||
}
|
||||
|
||||
public int dp(int[] arr, int aim) {
|
||||
if (aim == 0) {
|
||||
return 1;
|
||||
}
|
||||
Info info = getInfo(arr);
|
||||
|
||||
int[] amounts = info.amounts;
|
||||
int[] zhangs = info.zhangs;
|
||||
int N = zhangs.length;
|
||||
|
||||
int[][] dp = new int[N + 1][aim + 1];
|
||||
dp[N][0] = 1;
|
||||
|
||||
for (int index = N - 1; index >= 0; index--) {
|
||||
for (int rest = 0; rest <= aim; rest++) {
|
||||
// int ways = 0;
|
||||
// for (int zhang = 0; zhang * amounts[index] <= rest && zhang <= zhangs[index]; zhang++) {
|
||||
// ways += dp[index + 1][rest - zhang * amounts[index]];
|
||||
// }
|
||||
// dp[index][rest] = ways;
|
||||
//判断和左边位置的依赖关系 当前=左+下-不越界的下左
|
||||
dp[index][rest] += dp[index + 1][rest];
|
||||
//左不越界
|
||||
if (rest - amounts[index] >= 0) {
|
||||
dp[index][rest] += dp[index][rest - amounts[index]];
|
||||
}
|
||||
//最左的张数不越界
|
||||
if (rest - (zhangs[index] + 1) * amounts[index] >= 0) {
|
||||
dp[index][rest] -= dp[index + 1][rest - (zhangs[index] + 1) * amounts[index]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dp[0][aim];
|
||||
|
||||
}
|
||||
|
||||
private Info getInfo(int[] arr) {
|
||||
Map<Integer, Integer> map = new HashMap<>();
|
||||
for (int amount : arr) {
|
||||
if (map.containsKey(amount)) {
|
||||
Integer count = map.get(amount);
|
||||
map.put(amount, count + 1);
|
||||
} else {
|
||||
map.put(amount, 1);
|
||||
}
|
||||
}
|
||||
Set<Integer> amountSet = map.keySet();
|
||||
int size = amountSet.size();
|
||||
int[] zhangs = new int[size];
|
||||
int[] amounts = new int[size];
|
||||
int index = 0;
|
||||
for (Integer amount : amountSet) {
|
||||
amounts[index] = map.get(amount);
|
||||
zhangs[index] = amount;
|
||||
index++;
|
||||
}
|
||||
return new Info(zhangs, amounts);
|
||||
}
|
||||
}
|
||||
|
||||
class 英雄砍死怪兽的概率 {
|
||||
|
||||
|
||||
public double process(int hp, int times, int M) {
|
||||
if (hp < 1 || times < 1 || M < 1) {
|
||||
return 0;
|
||||
}
|
||||
double all = Math.pow((M + 1), times);
|
||||
double kill = f(hp, times, M);//存活下来的情况
|
||||
return 1 - kill / all;
|
||||
}
|
||||
|
||||
|
||||
public double dp(int hp, int times, int M) {
|
||||
if (hp < 1 || times < 1 || M < 1) {
|
||||
return 0;
|
||||
}
|
||||
double all = Math.pow((M + 1), times);
|
||||
int[][] dp = new int[times + 1][hp + 1];
|
||||
for (int i = 1; i <= hp; i++) {
|
||||
dp[0][i] = 1;
|
||||
}
|
||||
for (int index = 1; index <= times; index++) {
|
||||
for (int h = 1; h <= hp; h++) {
|
||||
// int ways = 0;
|
||||
// for (int i = 0; i <= M; i++) {
|
||||
// ways += (h - i) >= 0 ? dp[index - 1][h - i] : 0;
|
||||
// }
|
||||
// dp[index][h] = ways;
|
||||
dp[index][h] = dp[index - 1][h] + dp[index][h - 1];
|
||||
if (h - M - 1 >= 0) {
|
||||
dp[index][h] -= dp[index - 1][h - M - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println(dp[times][hp]);
|
||||
System.out.println(all);
|
||||
return (double) (all - dp[times][hp]) / (double) all;
|
||||
}
|
||||
|
||||
private double f(int hp, int times, int M) {
|
||||
if (0 == times) {
|
||||
return hp > 0 ? 1 : 0;
|
||||
}
|
||||
if (hp <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ways = 0;
|
||||
for (int i = 0; i <= M; i++) {
|
||||
ways += f(hp - i, times - 1, M);
|
||||
}
|
||||
return ways;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
英雄砍死怪兽的概率 aaa = new 英雄砍死怪兽的概率();
|
||||
|
||||
System.out.println(aaa.dp(30, 3, 10));
|
||||
// System.out.println(aaa.process(10, 1, 10));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class 数组中组成固定和可重复选的个数最少 {
|
||||
|
||||
|
||||
public int process(int[] arr, int index, int rest) {
|
||||
if (index == arr.length) {
|
||||
return rest == 0 ? 0 : Integer.MAX_VALUE;
|
||||
}
|
||||
int ways = Integer.MAX_VALUE;
|
||||
for (int zhang = 0; zhang * arr[index] <= rest; zhang++) {
|
||||
int next = process(arr, index + 1, rest - zhang * arr[index]);
|
||||
if (next != Integer.MAX_VALUE) {
|
||||
ways = Math.min(ways, next + zhang);
|
||||
}
|
||||
}
|
||||
return ways;
|
||||
}
|
||||
|
||||
public int dp(int[] arr, int aim) {
|
||||
int N = arr.length;
|
||||
|
||||
int[][] dp = new int[N + 1][aim + 1];
|
||||
dp[N][0] = 0;
|
||||
for (int i = 1; i <= aim; i++) {
|
||||
dp[N][i] = Integer.MAX_VALUE;
|
||||
}
|
||||
for (int index = N - 1; index >= 0; index--) {
|
||||
for (int rest = 0; rest <= aim; rest++) {
|
||||
dp[index][rest] = dp[index + 1][rest];
|
||||
if (rest - arr[index] >= 0 && dp[index][rest - arr[index]] != Integer.MAX_VALUE) {
|
||||
dp[index][rest] = Math.min(dp[index][rest], dp[index][rest - arr[index] + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[0][aim];
|
||||
}
|
||||
}
|
||||
|
||||
class 数字的分裂的个数 {
|
||||
|
||||
//precess(1,N)
|
||||
public int process(int pre, int rest) {
|
||||
if (rest == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (pre > rest) {
|
||||
return 0;
|
||||
}
|
||||
int ways = 0;
|
||||
for (int i = pre; i <= rest; i++) {
|
||||
ways += process(i, rest - i);
|
||||
}
|
||||
return ways;
|
||||
}
|
||||
|
||||
|
||||
public int dp(int N) {
|
||||
if (N <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (N == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int[][] dp = new int[N + 1][N + 1];
|
||||
for (int i = 1; i <= N; i++) {
|
||||
dp[i][0] = 1;
|
||||
dp[i][i] = 1;
|
||||
}
|
||||
for (int pre = N - 1; pre > 0; pre--) {
|
||||
for (int rest = pre + 1; rest <= N; rest++) {
|
||||
// int ways = 0;
|
||||
// for (int i = pre; i <= rest; i++) {
|
||||
// ways += dp[i][rest - i];
|
||||
// }
|
||||
// dp[pre][rest] = ways;
|
||||
dp[pre][rest] = dp[pre + 1][rest] + dp[pre][rest - pre];
|
||||
}
|
||||
}
|
||||
return dp[1][N];
|
||||
}
|
||||
}
|
||||
|
||||
class 拆分两个集合累加和接近 {
|
||||
|
||||
public int process(int[] arr, int index, int sum, int targetSum) {
|
||||
if (index == arr.length) {
|
||||
return sum;
|
||||
}
|
||||
//不选i
|
||||
int p1 = process(arr, index + 1, sum, targetSum);
|
||||
//选i
|
||||
int p2 = 0;
|
||||
if (arr[index] + sum <= targetSum) {
|
||||
p2 = process(arr, index + 1, sum + arr[index], targetSum);
|
||||
}
|
||||
return Math.max(p1, p2);
|
||||
}
|
||||
|
||||
public int process(int[] arr, int index, int targetSum) {
|
||||
if (index == arr.length) {
|
||||
return 0;
|
||||
}
|
||||
//不选i
|
||||
int p1 = process(arr, index + 1, targetSum);
|
||||
//选i
|
||||
int p2 = 0;
|
||||
if (arr[index] <= targetSum) {
|
||||
p2 = arr[index] + process(arr, index + 1, targetSum - arr[index]);
|
||||
}
|
||||
return Math.max(p1, p2);
|
||||
}
|
||||
|
||||
|
||||
public int dp(int[] arr) {
|
||||
if (arr == null || arr.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
int N = arr.length;
|
||||
int sum = 0;
|
||||
for (int num : arr) {
|
||||
sum += num;
|
||||
}
|
||||
sum /= sum;
|
||||
int[][] dp = new int[N + 1][sum + 1];
|
||||
|
||||
for (int index = N - 1; index >= 0; index--) {
|
||||
for (int rest = 0; rest <= sum; rest++) {
|
||||
//不选i
|
||||
int p1 = dp[index + 1][rest];
|
||||
//选i
|
||||
int p2 = 0;
|
||||
if (arr[index] <= rest) {
|
||||
p2 = arr[index] + dp[index + 1][rest - arr[index]];
|
||||
}
|
||||
dp[index][rest] = Math.max(p1, p2);
|
||||
}
|
||||
}
|
||||
return dp[0][sum];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
拆分两个集合累加和接近 aaa = new 拆分两个集合累加和接近();
|
||||
int[] arr = {1, 2, 3, 4};
|
||||
System.out.println(aaa.process(arr, 0, 0, 5));
|
||||
}
|
||||
}
|
||||
|
||||
class 拆分两个集合累加和接近个数一半 {
|
||||
|
||||
public int m(int[] arr) {
|
||||
if (arr == null || arr.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
int N = arr.length;
|
||||
int sum = 0;
|
||||
for (int num : arr) {
|
||||
sum += num;
|
||||
}
|
||||
if ((N & 1) == 0) {
|
||||
return process(arr, 0, sum / 2, N / 2);
|
||||
} else {
|
||||
return Math.max(process(arr, 0, sum / 2, N / 2), process(arr, 0, sum / 2, N / 2 + 1));
|
||||
}
|
||||
}
|
||||
|
||||
public int dp(int[] arr) {
|
||||
if (arr == null || arr.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
int N = arr.length;
|
||||
int sum = 0;
|
||||
for (int num : arr) {
|
||||
sum += num;
|
||||
}
|
||||
sum /= 2;
|
||||
int num = (N + 1) / 2;
|
||||
int[][][] dp = new int[N + 1][sum + 1][num + 1];
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
for (int j = 0; j < sum; j++) {
|
||||
for (int k = 0; k < num; k++) {
|
||||
dp[i][j][k] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < sum; j++) {
|
||||
dp[N][j][0] = 0;
|
||||
}
|
||||
|
||||
for (int index = N - 1; index >= 0; index--) {
|
||||
for (int rest = 0; rest < sum; rest++) {
|
||||
for (int count = 0; count < num; count++) {
|
||||
|
||||
int p1 = dp[index + 1][rest][count];
|
||||
int p2 = -1;
|
||||
int next = -1;
|
||||
if (count > 0 && arr[index] <= rest) {
|
||||
next = dp[index + 1][rest - arr[index]][count - 1];
|
||||
}
|
||||
if (next != -1) {
|
||||
p2 = arr[index] + next;
|
||||
}
|
||||
dp[index][rest][count] = Math.max(p1, p2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((N & 1) == 0) {
|
||||
return dp[0][sum][num];
|
||||
} else {
|
||||
return Math.max(dp[0][sum][num], dp[0][sum][num - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
public int process(int[] arr, int index, int rest, int count) {
|
||||
if (index == arr.length) {
|
||||
return count == 0 ? 0 : -1;
|
||||
}
|
||||
int p1 = process(arr, index + 1, rest, count);
|
||||
int p2 = -1;
|
||||
int next = -1;
|
||||
if (count > 0 && arr[index] <= rest) {
|
||||
next = process(arr, index + 1, rest - arr[index], count - 1);
|
||||
}
|
||||
if (next != -1) {
|
||||
p2 = arr[index] + next;
|
||||
}
|
||||
return Math.max(p1, p2);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
拆分两个集合累加和接近个数一半 aaa = new 拆分两个集合累加和接近个数一半();
|
||||
int[] arr = {1, 2, 3, 4};
|
||||
System.out.println(aaa.process(arr, 0, 5, 2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in new issue