Java 求最大值的优化算法
我需要设计一个算法,以找到在预定义的(步长)下沿int[]步进得到的最大值 输入是我们可以“使用”每个步长的次数;由n2、n5和n10给出。n2表示在阵列中移动2个点,n5表示5个点,n10表示10个点。我们只能前进(从左到右) int[]包含值1..5,数组大小为(n2*2+n5*5+n10*10)。起点是int[0] 示例:我们从int[0]开始。从这里我们可以移动到int[0+2]==3,int[0+5]==4或int[0+10]==1。让我们转到int[5],因为它的值最高。从int[5]我们可以移动到int[5+2],int[5+5]或int[5+10]等等 我们应该以2、5或10的步长沿着阵列移动(并且我们只能使用每个步长n2、n5和n10次),这样我们就可以在阵列中步进以收集尽可能高的总和Java 求最大值的优化算法,java,arrays,algorithm,dynamic-programming,Java,Arrays,Algorithm,Dynamic Programming,我需要设计一个算法,以找到在预定义的(步长)下沿int[]步进得到的最大值 输入是我们可以“使用”每个步长的次数;由n2、n5和n10给出。n2表示在阵列中移动2个点,n5表示5个点,n10表示10个点。我们只能前进(从左到右) int[]包含值1..5,数组大小为(n2*2+n5*5+n10*10)。起点是int[0] 示例:我们从int[0]开始。从这里我们可以移动到int[0+2]==3,int[0+5]==4或int[0+10]==1。让我们转到int[5],因为它的值最高。从int[5
public class Main {
private static int n2 = 5;
private static int n5 = 3;
private static int n10 = 2;
private static final int[] pokestops = new int[n2 * 2 + n5 * 5 + n10 * 10];
public static void main(String[] args) {
Random rand = new Random();
for (int i = 0; i < pokestops.length; i++) {
pokestops[i] = Math.abs(rand.nextInt() % 5) + 1;
}
System.out.println(Arrays.toString(pokestops));
//TODO: return the maximum value possible
}
}
输出是可能的最大值
public class Main {
private static int n2 = 5;
private static int n5 = 3;
private static int n10 = 2;
private static final int[] pokestops = new int[n2 * 2 + n5 * 5 + n10 * 10];
public static void main(String[] args) {
Random rand = new Random();
for (int i = 0; i < pokestops.length; i++) {
pokestops[i] = Math.abs(rand.nextInt() % 5) + 1;
}
System.out.println(Arrays.toString(pokestops));
//TODO: return the maximum value possible
}
}
公共类主{
私有静态int n2=5;
专用静态int n5=3;
专用静态int n10=2;
私有静态最终整数[]pokestops=新整数[n2*2+n5*5+n10*10];
公共静态void main(字符串[]args){
Random rand=新的Random();
for(int i=0;i
这是一个伪代码的答案(我没有运行它,但它应该可以工作)
用-1填充dp。
dp(整数id、整数2步计数、整数5步计数、整数10步计数){
如果(id>array_length-1)返回0;
如果(dp[id][2stepcount][5stepcount][10stepcount]!=-1)返回dp[id][2stepcount][5stepcount][10stepcount];
else dp[id][2步数][5步数][10步数]=0;
int 2step=2stepcount
打电话给dp(0,0,0,0),答案是dp[0][0][0]
如果你想倒退,那么你可以这样做:
fill dp with -1.
dp(int id, int 2stepcount, int 5stepcount, int 10stepcount) {
if(id > array_length - 1 || id < 0) return 0;
if(dp[id][2stepcount][5stepcount][10stepcount] != -1) return dp[id][2stepcount][5stepcount][10stepcount];
else dp[id][2stepcount][5stepcount][10stepcount] = 0;
int 2stepForward = 2stepcount < max2stepcount? dp(id + 2, 2stepcount + 1, 5stepcount, 10stepcount) : 0;
int 5stepForward = 5stepcount < max5stepcount? dp(id + 5, 2stepcount, 5stepcount + 1, 10stepcount) : 0;
int 10stepForward = 10stepcount < max10stepcount? dp(id + 10, 2stepcount, 5stepcount, 10stepcount + 1) : 0;
int 2stepBackward = 2stepcount < max2stepcount? dp(id - 2, 2stepcount + 1, 5stepcount, 10stepcount) : 0;
int 5stepBackward = 5stepcount < max5stepcount? dp(id - 5, 2stepcount, 5stepcount + 1, 10stepcount) : 0;
int 10stepBackward = 10stepcount < max10stepcount? dp(id - 10, 2stepcount, 5stepcount, 10stepcount + 1) : 0;
dp[id][2stepcount][5stepcount][10stepcount] += array[id] + max(2stepForward, 5stepForward, 10stepForward, 2stepBackward, 5backForward, 10backForward);
return dp[id][2stepcount][5stepcount][10stepcount];
}
用-1填充dp。
dp(整数id、整数2步计数、整数5步计数、整数10步计数){
如果(id>array|u length-1 | id<0)返回0;
如果(dp[id][2stepcount][5stepcount][10stepcount]!=-1)返回dp[id][2stepcount][5stepcount][10stepcount];
else dp[id][2步数][5步数][10步数]=0;
int 2STEPTFORWARD=2STEPCUNT
但是您的路径没有得到充分的探索,因为如果索引为负数或大于数组大小-1,我们将停止,我想您可以添加环绕功能。您需要计算以下动态编程dp[c2][c5][c10][id]-其中c2是您已步进2的次数,c5-乘以5,c10-乘10和id-您当前的位置在哪里。我将只为c2和c5编写示例,它可以很容易地扩展
int[][][][] dp = new int[n2 + 1][n5 + 1][pokestops.length + 1];
for (int[][][] dp2 : dp) for (int[][] dp3 : dp2) Arrays.fill(dp3, Integer.MAX_VALUE);
dp[0][0][0] = pokestops[0];
for (int c2 = 0; c2 <= n2; c2++) {
for (int c5 = 0; c5 <= n5; c5++) {
for (int i = 0; i < pokestops.length; i++) {
if (c2 < n2 && dp[c2 + 1][c5][i + 2] < dp[c2][c5][i] + pokestops[i + 2]) {
dp[c2 + 1][c5][i + 2] = dp[c2][c5][i] + pokestops[i + 2];
}
if (c5 < n5 && dp[c2][c5 + 1][i + 5] < dp[c2][c5][i] + pokestops[i + 5]) {
dp[c2][c5 + 1][i + 5] = dp[c2][c5][i] + pokestops[i + 5];
}
}
}
}
int[]dp=newint[n2+1][n5+1][pokestops.length+1];
for(int[][]dp2:dp)for(int[]dp3:dp2)数组。fill(dp3,Integer.MAX_值);
dp[0][0][0]=pokestops[0];
对于(int c2=0;c2这是一个解决方案,但我不确定它有多最优
我对它做了一些优化,但我认为可以做得更多
我把它和有问题的例子一起贴了出来
import java.util.Arrays;
import java.util.Random;
public class FindMax {
private static int n2 = 5;
private static int n5 = 3;
private static int n10 = 2;
private static final int[] pokestops = new int[n2 * 2 + n5 * 5 + n10 * 10];
public static int findMaxValue(int n2, int n5, int n10, int pos, int[] pokestops) {
System.out.print("|");
if (n2 <= 0 || n5 <= 0 || n10 <= 0) {
return 0;
}
int first;
int second;
int third;
if (pokestops[pos] == 5 || ((first = findMaxValue(n2 - 1, n5, n10, pos + 2, pokestops)) == 5) || ((second = findMaxValue(n2, n5 - 1, n10, pos + 5, pokestops)) == 5) || ((third = findMaxValue(n2, n5, n10 - 1, pos + 10, pokestops)) == 5)) {
return 5;
}
return Math.max(Math.max(Math.max(first, second), third), pokestops[pos]);
}
public static void main(String[] args) {
Random rand = new Random();
for (int i = 0; i < pokestops.length; i++) {
pokestops[i] = Math.abs(rand.nextInt() % 5) + 1;
}
System.out.println(Arrays.toString(pokestops));
//TODO: return the maximum value possible
int max = findMaxValue(n2, n5, n10, 0, pokestops);
System.out.println("");
System.out.println("Max is :" + max);
}
导入java.util.array;
导入java.util.Random;
公共类FindMax{
私有静态int n2=5;
专用静态int n5=3;
专用静态int n10=2;
私有静态最终整数[]pokestops=新整数[n2*2+n5*5+n10*10];
公共静态int findMaxValue(int n2、int n5、int n10、int pos、int[]pokestops){
系统输出打印(“|”);
如果(n2我知道目标语言是java,但我喜欢pyhton,转换不会很复杂。
您可以定义一个四维数组dp,其中dp[i][a][b][c]是您可以定义的最大值
当你已经有了a长度2,b长度5和c长度
10。我通常会得到更干净的代码
import random
values = []
memo = {}
def dp(pos, n2, n5, n10):
state = (pos, n2, n5, n10)
if state in memo:
return memo[state]
res = values[pos]
if pos + 2 < len(values) and n2 > 0:
res = max(res, values[pos] + dp(pos + 2, n2 - 1, n5, n10))
if pos + 5 < len(values) and n5 > 0:
res = max(res, values[pos] + dp(pos + 5, n2, n5 - 1, n10))
if pos + 10 < len(values) and n10 > 0:
res = max(res, values[pos] + dp(pos + 10, n2, n5, n10 - 1))
memo[state] = res
return res
n2, n5, n10 = 5, 3, 2
values = [random.randint(1, 5) for _ in range(n2*2 + n5*5 + n10*10)]
print dp(0, n2, n5, n10)
随机导入
值=[]
备忘录={}
def dp(位置、n2、n5、n10):
状态=(位置,n2,n5,n10)
如果在备忘录中注明:
返回备忘录[状态]
res=值[pos]
如果pos+20:
res=最大值(res,数值[pos]+dp(pos+2,n2-1,n5,n10))
如果位置+50:
res=最大值(res,数值[pos]+dp(pos+5,n2,n5-1,n10))
如果位置+100:
res=最大值(res,数值[pos]+dp(pos+10,n2,n5,n10-1))
备忘录[状态]=res
返回res
n2,n5,n10=5,3,2
值=[范围内(n2*2+n5*5+n10*10)的随机.randint(1,5)]
打印dp(0、n2、n5、n10)
疑似家庭作业。未测试:
import java.util.Arrays;
import java.util.Random;
public class Main {
private static Step[] steps = new Step[]{
new Step(2, 5),
new Step(5, 3),
new Step(10, 2)
};
private static final int[] pokestops = new int[calcLength(steps)];
private static int calcLength(Step[] steps) {
int total = 0;
for (Step step : steps) {
total += step.maxCount * step.size;
}
return total;
}
public static void main(String[] args) {
Random rand = new Random();
for (int i = 0; i < pokestops.length; i++) {
pokestops[i] = Math.abs(rand.nextInt() % 5) + 1;
}
System.out.println(Arrays.toString(pokestops));
int[] initialCounts = new int[steps.length];
for (int i = 0; i < steps.length; i++) {
initialCounts[i] = steps[i].maxCount;
}
Counts counts = new Counts(initialCounts);
Tree base = new Tree(0, null, counts);
System.out.println(Tree.max.currentTotal);
}
static class Tree {
final int pos;
final Tree parent;
private final int currentTotal;
static Tree max = null;
Tree[] children = new Tree[steps.length*2];
public Tree(int pos, Tree parent, Counts counts) {
this.pos = pos;
this.parent = parent;
if (pos < 0 || pos >= pokestops.length || counts.exceeded()) {
currentTotal = -1;
} else {
int tmp = parent == null ? 0 : parent.currentTotal;
this.currentTotal = tmp + pokestops[pos];
if (max == null || max.currentTotal < currentTotal) max = this;
for (int i = 0; i < steps.length; i++) {
children[i] = new Tree(pos + steps[i].size, this, counts.decrement(i));
// uncomment to allow forward-back traversal:
//children[2*i] = new Tree(pos - steps[i].size, this, counts.decrement(i));
}
}
}
}
static class Counts {
int[] counts;
public Counts(int[] counts) {
int[] tmp = new int[counts.length];
System.arraycopy(counts, 0, tmp, 0, counts.length);
this.counts = tmp;
}
public Counts decrement(int i) {
int[] tmp = new int[counts.length];
System.arraycopy(counts, 0, tmp, 0, counts.length);
tmp[i] -= 1;
return new Counts(tmp);
}
public boolean exceeded() {
for (int count : counts) {
if (count < 0) return true;
}
return false;
}
}
static class Step {
int size;
int maxCount;
public Step(int size, int maxCount) {
this.size = size;
this.maxCount = maxCount;
}
}
}
导入java.util.array;
进口