我遇到了一个算法问题。请为我提出一些针对以下问题的有效算法
问题是
查找数量的子数组(范围在0< R< N之间),其总和可以被给定的数字整除。
我的方法:
Input: 0 5 3 8 2 1
Sum: 0 0 5 8 16 18 19
Mod 3: 0 0 2 2 1 0 1
否。选择0,1或2的方法是NC2
问题:我是否被要求在某个范围内进行选择,即从2到5,因此阵列将成为:
3 8 2 1
我是否必须重新计算总和和Mod,或者原始的MOd数组会给我一个正确的答案
第二个问题:如果我改变了一个元素,即8 is change to 11
,它是怎么回事将是有效的
对于上述问题,我正在考虑使用BIT
dp [4] [最大。元素]如果mod是0更新dp [0]如果1更新dp [1]那么如何更新如果VAlue在索引处更改
答案 0 :(得分:0)
检查一下:
这个子程序找到最大的子阵列,其总和除以3。 它只在阵列上运行一次,没有额外的空间。 这里是c ++代码:
int largest_3_divider_subarray(int* a, int len){
int cum_sum = 0;
int index_of_first_one = -1;
int index_of_first_two = -1;
int absolute_maximal = 0;
int current_maximal = 0;
bool flag1 = 1, flag2 = 1;
for(int i = 0; i < len; ++i){
cum_sum += a[i];
switch (cum_sum%3)
{
case 1:
if(flag1){
index_of_first_one = i;
flag1 = 0;
}else
current_maximal = i - index_of_first_one;
break;
case 2:
if(flag2){
index_of_first_two = i;
flag2 = 0;
}else
current_maximal = i - index_of_first_two;
break;
case 0:
current_maximal = i;
}
if(current_maximal > absolute_maximal)
absolute_maximal = current_maximal;
}
return absolute_maximal + 1;
}
int main() {
int A[]= {6,8,-2,0,9,13,1};
int k = largest_3_divider_subarray(A,7);
return 0;
}
答案 1 :(得分:0)
这可能是一个竞赛问题,但是有一个dp方法。如果你想解决正在运行的竞赛问题,你需要将它与分段树结合起来。
基本理念:
(dp的特点:我们尝试解决一个子问题,然后使用获得的值,我们尝试解决更大实例的子问题)。
如果要解决codechef
中的运行竞赛问题,则必须与分段树结合使用有一些很好的教程可用于分段树
答案 2 :(得分:0)
public static int largest_3_divider_subarray(int a[]){
int cum_sum = 0;
int index_of_first_one = -1;
int index_of_first_two = -1;
int absolute_maximal = 0;
int current_maximal = 0;
boolean flag1 = true, flag2 = true;
for(int i = 0; i < a.length; ++i){
cum_sum += a[i];
switch ((cum_sum%3))
{
case 1:
case -2:
if(flag1){
index_of_first_one = i;
flag1 = false;
}else
current_maximal = i - index_of_first_one;
break;
case 2:
case -1:
if(flag2){
index_of_first_two = i;
flag2 = false;
}else
current_maximal = i - index_of_first_two;
break;
case 0:
current_maximal = i+1;
}
if(current_maximal > absolute_maximal)
absolute_maximal = current_maximal;
}
return absolute_maximal ;
}