📌  相关文章
📜  从0到N的整数对的最大设置位计数,得出的总和为N(1)

📅  最后修改于: 2023-12-03 15:36:15.463000             🧑  作者: Mango

从0到N的整数对的最大设置位计数

介绍

这道题目需要计算从0到N之间的所有整数对(i,j)的二进制表示中出现1的最多的个数,并将其相加。其中,N是一个正整数。

例如,当N为10时,结果为:

  • 0和1的最大设置位计数为1
  • 2和3的最大设置位计数为2
  • 4和5的最大设置位计数为2
  • 6和7的最大设置位计数为3
  • 8和9的最大设置位计数为1

因此,总和为 1 + 2 + 2 + 3 + 1 = 9

解法

一个比较朴素的解法是对每个整数对进行二进制运算,统计1的个数。但是这样做的时间复杂度为O(N^2),显然不可取。

更加高效的解法是通过位运算和动态规划。具体步骤如下:

  1. 为了方便,我们可以将N的二进制表示从高到低分成第1位,第2位...第K位,其中K为N的二进制表示中最高位的位置。
  2. 对于第i位,我们可以得到这一位上最大设置位计数的表格,记为dp[i]。
  3. 对于每个数x,我们可以用它的二进制表示的最高位位置j来计算它的dp[j]。
  4. 最后将dp[0]到dp[K]的总和相加即可。

以N=10为例,上述过程如下:

| i | dp[i] | |---|-------| | 0 | 1 | | 1 | 1 | | 2 | 2 | | 3 | 2 | | 4 | 2 | | 5 | 2 | | 6 | 3 | | 7 | 3 | | 8 | 1 | | 9 | 1 | | | | | | | | | | | K | 4 |

其中,dp[i]表示第i位的最大设置位计数。例如,dp[2]表示二进制的第2位的最大设置位计数为2。

def count_bits(n: int) -> int:
    if n == 0:
        return 0
    dp = [0]*(n+1)
    dp[0] = 1
    for i in range(1, n+1):
        dp[i] = dp[i&(i-1)] + 1
    return sum(dp)
总结

本题需要计算从0到N之间的所有整数对(i,j)的二进制表示中出现1的最多的个数,并将其相加。通过使用位运算和动态规划可以实现O(N)的时间复杂度。