Java 查找范围内数组单元格中的数字之和
我正在准备一场编码比赛。在档案中我发现了这个问题: 给定一个N个正整数的序列i1,i2,…,iN。此外,将分别为您提供一个起始整数b和下限和上限整数min和max。请注意,0≤闵≤b≤马克斯总是这样 顺序游戏如下所示。最初,你的分数是b。在步骤1中,您可以将i1添加到b或从b中减去i1以获得新的分数B1。在步骤2中,通过加上或减去i2来更新b1,以获得新的分数b2。以这种方式继续,在步骤j中,通过添加或减去ij来更新bj-1,以获得新的分数bj。规则是,每个分数bj应始终位于最小值和最大值之间,包括:即,对于每个j,1≤j≤N,应该是这样的,min≤北京≤最大值。使用序列中的最后一个数字后,您的最终分数为bN 你的目标是在按照规则比赛的同时最大化你的最终得分。如果在不超出最小值和最大值界限的情况下无法完成所有N个步骤,则您的分数为-1 例如,假设您拥有的数字序列为[2,3,4],b为5,min为0,max为8。在步骤1之后,分数可以是3或7。步骤2之后,分数可以是0、4或6。10分是不允许的,因为最高分是8分。步骤3之后,分数可以是0、2、4或8。因此,在这个游戏中,你可以在序列结束时获得的最大分数是8 输入格式 输入的第一行包含四个整数N、b、min和max,其含义如上所述。第二行输入包含N个空格分隔的整数,这是玩游戏的顺序 输出格式 您的输出应该是由一个整数组成的单行,这是您可以达到的最大最终分数 测试数据 在所有情况下,N≤103和0≤闵≤b≤马克斯≤103 样本输入Java 查找范围内数组单元格中的数字之和,java,arrays,optimization,Java,Arrays,Optimization,我正在准备一场编码比赛。在档案中我发现了这个问题: 给定一个N个正整数的序列i1,i2,…,iN。此外,将分别为您提供一个起始整数b和下限和上限整数min和max。请注意,0≤闵≤b≤马克斯总是这样 顺序游戏如下所示。最初,你的分数是b。在步骤1中,您可以将i1添加到b或从b中减去i1以获得新的分数B1。在步骤2中,通过加上或减去i2来更新b1,以获得新的分数b2。以这种方式继续,在步骤j中,通过添加或减去ij来更新bj-1,以获得新的分数bj。规则是,每个分数bj应始终位于最小值和最大值之间,
3 5 0 8 2 3 4
样本输出
8
现在,我尝试使用递归技术来解决这个问题,但是太慢了。我检查了所有可能的安排。也许这就是我错的地方。这是我的密码:
import java.io.*;
class seq2
{
public static void recursive(int ar[],int turn,int sum,int max,int min,int n,int mega[])
{
if(turn!=n)
{
if(ar[turn]+sum<=max)
{
sum=sum+ar[turn];
recursive(ar,turn+1,sum,max,min,n,mega);
sum=sum-ar[turn];
}
if(sum-ar[turn]>=0)
{
sum=sum-ar[turn];
recursive(ar,turn+1,sum,max,min,n,mega);
sum=ar[turn]+sum;
}
if((ar[turn]+sum>max)&&(sum-ar[turn]<min))
{
sum=-1;
}
}
else
{
if(sum>mega[0])
{
mega[0]=sum;
}
}
}
public static void main(String args[])throws IOException
{
DataInputStream in=new DataInputStream(System.in);
int n=Integer.parseInt(in.readLine());
int b=Integer.parseInt(in.readLine());
int min=Integer.parseInt(in.readLine());
int max=Integer.parseInt(in.readLine());
System.out.println();
int ar[]=new int[n],a;
for(int i=0;i<n;i++)
{
a=Integer.parseInt(in.readLine());
ar[i]=a;
}
int mega[]={-1};
recursive(ar,0,b,max,min,n,mega);
System.out.println(mega[0]);
}
}
import java.io.*;
第2类
{
公共静态无效递归(int-ar[],int-turn,int-sum,int-max,int-min,int-n,int-mega[])
{
如果(转动!=n)
{
如果(ar[转动]+总和=0)
{
总和=总和应收账款[转];
递归(ar、转角+1、和、最大、最小、n、兆);
总和=应收账款[转数]+总和;
}
如果((应收账款周转次数+总和>最大值)和((应收账款周转次数总和]百万[0])
{
兆[0]=和;
}
}
}
公共静态void main(字符串args[])引发IOException
{
DataInputStream in=新的DataInputStream(System.in);
int n=Integer.parseInt(in.readLine());
intb=Integer.parseInt(in.readLine());
int min=Integer.parseInt(in.readLine());
int max=Integer.parseInt(in.readLine());
System.out.println();
int ar[]=新的int[n],a;
对于(int i=0;ipublicstaticvoidrecursive(int-ar[],int-turn,int-sum,int-max,int-min,int-mega[])
{
整数加,减;
如果(转动!=ar长度)
{
加=和+应收账款[转];
如果(加上=最小值)
递归(ar、转角+1、负、最大、最小、最大);
}
如果(总和>百万[0])
兆[0]=和;
}
成功地将时间减少了30%谢谢aviad,但即使在您的帮助下,它也无法计算只有50个单元的阵列的结果谢谢aviad,但即使在您的帮助下,程序也无法计算只有50个单元的阵列的结果为什么?有什么问题吗?据我猜测,它似乎没有占用太多空间,问题是我M使用一种递归方法,它可以处理每一个可能的结果,当涉及到太多单元的数组时,运行时间呈指数增长。这就是为什么我认为我的代码效率低下。如果你能提出一个更好的方法,这将是一个很大的帮助。我几乎可以肯定这个问题是NP-难的,这意味着没有多项式时间算法。hm是为解决这个问题而存在的
public static void recursive(int ar[], int turn, int sum, int max, int min, int mega[])
{
int plus, minus;
if (turn != ar.length)
{
plus = sum + ar[turn];
if (plus <= max)
recursive(ar, turn + 1, plus, max, min, mega);
minus = sum - ar[turn];
if (minus >= min)
recursive(ar, turn + 1, minus, max, min, mega);
}
else if (sum > mega[0])
mega[0] = sum;
}