如何在给定操作恰好k次后才能找到可以获得的不同阵列的总数?

时间:2016-06-24 13:19:27

标签: algorithm dynamic-programming combinatorics

给定数组,数组内的元素在[-10^6, 10^6]范围内。 我们还有一个整数k,我们需要通过恰好k次应用一个操作来找到可以获得多少个不同的数组。唯一的操作是选择数组的任何元素并将其乘以-1

例如,数组A = {1, 2, 1}k = 2k操作后获得的不同数组为4{1, 2, 1}{-1, -2, 1},{{ 1}},{-1, 2, -1}

虽然提供了代码和解释here,但很难理解。请有人简化解释或提供其他方法来解决问题。感谢。

2 个答案:

答案 0 :(得分:1)

让数组的大小为n。首先要看到答案并不取决于所完成的操作顺序。

考虑两种情况:

案例1:数组中没有零和

案例2:数组中有非零数量的零。

考虑案例1:

  

子案例1 :元素数量> =操作数量,即 n> ķ

     

假设我们对每个元素允许最多1个运算,我们可以看到我们可以得到 n c k 具有 k 的不同数组从原始数组中更改了元素。

     

但是当我们对一个元素进行2次操作时会发生什么?元素基本上没有改变,并且记住操作的顺序没有改变,你可以这样说:你拿出初始数组,选择一个元素,将它乘以-1两次因此你现在使用的是精确的原始数组,但手中只有 k-2 个操作,这意味着我们最初丢弃了2个k机会。现在我们可以在每个元素上仔细执行 k-2 操作,并获得 n c k-2 不同的数组。同样地,你可以扔掉4,6,8 ......机会并获得 n c k-4 n c 每个案例分别为k-6 n c k-8 ,.....阵列。

     

这导致 n c k + n c k-2 + n c k-4 + n c k-6 + n c k-8 < / sub> + .......如果数组中没有元素为零,则可能的数组数。

     

子案例2 n&lt; ķ

     

由于操作次数大于元素数量,因此必须丢弃一些操作,因为必须对至少一个元素应用多个操作。因此,如果n和k都是偶数或两者都是奇数,你应该抛出你的操作kn并且剩下n个操作,从这里它只是子情况1.如果一个是奇数而一个是偶数你必须扔掉k -n + 1你的操作并且左右有n-1个操作,从这一点开始它只是子案例1。您可以尝试获取此案例的表达式。

考虑案例2:

  

请注意,在之前的情况下,您只能丢弃偶数次操作。

     

即使在这里,也会出现 n&gt; = k n <&lt; ķ

     

对于 n&gt; = k 案例:

     

由于存在至少一个零,因此您现在可以通过在任何零上应用该数量的操作来丢弃任意数量的操作,因为将零乘以-1并不会影响它。

     

所以这里的答案只是 n c k + n c k-1 + n c k-2 + n c k-3 + n c k-4 + .......

     

n&lt; k 案例:

     

答案是 n c n + n c n-1 + n < / sup> c n-2 + n c n-3 + n c n-4 + ....... = 2 n

我认为这是一个动态编程问题,因为你必须计算 n c r 的总和。逻辑上,这是一个组合问题。

答案 1 :(得分:1)

好的,让我们来看看代码,
首先有这个函数nChoosek:它是一个计算组合计算器的函数,这是用来解决问题的函数
Conbinaison基本上是一个集合的选择部分的数目https://en.wikipedia.org/wiki/Combination
示例数组{1,2,3}如果我告诉你从阵列这三个项目选择了两个项是丝束的组合从三,在代码中它是nChoosek(2,3)=卡{(1,2),(2,3),(1,3)} = 3
如果我们考虑这三个附加条件的问题 1-你不能将相同的项目相乘两次 2 n <= k
3-阵列中没有零 这里的解决方案是nChoosek(k,n),但由于存在这些约束,我们必须处理它们中的每一个。 对于第一个,我们可以将相同的项相乘两次:所以对于nChoosek(k,n),如果我们将项(或许多)乘以两次,我们应该得到的数组数。 但是当我们将单个项目相乘两次时,让我们考虑组合:这里我们丢失了两次乘法而没有改变数组,所以我们的组合数将是nChoosek(k -2,n)
同样的方法,如果我们决定将两个项目相乘两次,结果将是nChoosek(k -4,n)
从那时起

for(; i >= 0; i -= 2){
        ans += nChoosek(n, i);
        ans = ans % (1000000007l);

    }

对于k>的情况; n应用算法意味着我们将两次乘以至少一个元素,这类似于将algorthm与k-2和n一起应用 如果k-2仍然大于n,我们可以通过相同的逻辑将其变换为与n和k-4等效的等等,直到k-2 * i <= n并且k-2 *(i + 1)> 0
很明显,这个k-2 * i将是n或n-1所以新的k将是n或n-1,这证明了这个代码

   if(k <= n){
        i = k;
    }else if((k % 2 == 0 && n % 2 == 0) || (k % 2 != 0 && n % 2 != 0)){
        i = n;
    }else if((k % 2 == 0 && n % 2 != 0) || (k % 2 != 0 && n % 2 == 0)){
        i = n - 1;
    }


现在故事为零,如果我们考虑T1 = {1,2,3}和T2 = {0,1,0,0,2,3,0,0,0}和k = 2你可以注意到这个交易使用长度= n且m为零的数组类似于处理长度= nm但没有零

的数组