了解Prime XOR的编辑 - HackerRank

时间:2017-07-06 20:56:25

标签: algorithm dynamic-programming boolean-logic xor

免责声明:此问题涉及相应社论的内容。因此,如果你想自己尝试这个问题,我不鼓励你阅读这篇文章。此外,我的问题遗漏了社论中提到的一些细节,所以请在阅读我的问题时参考社论。

另外,请记住,我不打算为HackerRank做广告;此外,我不会因编辑,问题描述或任何其他被HackerRank或附属方侵犯版权的材料而受到赞誉。

实际问题

我正在尝试理解这篇problem的社论。具体来说,我感到困惑的部分是以下代码:

...
for(int i=1;i<=k;i++) {
    for(int j=0;j<8192;j++) {
        mem[flag][j] = (mem[flag^1][j]*(1+(a[v[i-1]])/2))%mod + (mem[flag^1][j^v[i-1]]*((a[v[i-1]]+1)/2))%mod;
        if(mem[flag][j]>=mod)
            mem[flag][j]%=mod;
    }
    flag = flag^1;
}

社论指出“......使用这个属性,我们可以编写一个O(N)动态编程解决方案,其8192常数因子,dp[i][j]将存储可以的子集数用第一个元素形成,使得子集中元素的xor和为j。“

从代码中可以看出mem基本上是dp,除了我无法理解flag的功能 - 是什么 flag?另外,我得到1 + (a[v[i - 1]])/2对应于[0,a [v [i - 1]]]中的平均数,而(a[v[i - 1]] + 1) / 2对应于同一时间间隔内的赔率数,但我不知道不知道它与一切有什么联系。

提前感谢您的努力。

2 个答案:

答案 0 :(得分:5)

标志

的说明

这是一种在使用动态编程时减少内存使用的标准方法。

这个想法是DP阵列的每一行通常只依赖于前一行。在这种情况下,不是存储整个2d DP [i] [j]数组,而是只使用数组的2行。

换句话说,如果i是偶数,则DP [i] [j]存储在mem [0] [j]中,如果i是奇数,则存储在mem [1] [j]中。 mem数组被重复使用多次,并且在每次迭代后保存完整DP阵列的最新两行。

复发说明

假设我们有5个特定值的副本v。有1 + 5/2种方法使xor为0(取0或4个副本)。有(1 + 5)/ 2种方法制作vor(取1,3或5份)。

因此,要创建新值j,我们可以从j开始并添加0或4个v副本,或者从j ^ v开始并添加1,3或5个副本。

答案 1 :(得分:0)

flag用于减少过多的内存使用,因为dp仅取决于先前的状态。

为什么循环[0,8192]:正如问题[a] i == 4500所给,那么当我们对两个数进行“或”运算时,它将达到8192。 Xor属性..