简单瞎搞题(状压dp bitset)
发布日期:2021-05-10 04:58:32 浏览次数:17 分类:精选文章

本文共 1119 字,大约阅读时间需要 3 分钟。

对于这个问题,我们使用位掩码技术(Bitset)来高效解决。该技术通过位操作来处理状态,避免传统动态规划中的计算量爆炸问题。

问题分析

题目给出$n$个区间,每个区间由$l$和$r$确定。每个区间内,可以选择一个数$j$在$l$到$r$之间,并计算$j$的平方。目标是找到所有可能平方数的总和的最小值。

方法思路

  • 动态规划(DP)思想:使用DP来记录每一步可能的平方数之和。
  • 位掩码技术:通过Bitset(一个支持位运算的二进制数组)来高效处理状态转移。
  • 初始化:DP的第0位初始化为1,表示$s=0$的初始状态。
  • 状态转移:在每个区间内,遍历所有可能的$j$,并将DP中的每个可能值与$j$的平方合并到新的状态中。
  • 解决方法

    #include 
    #include
    using namespace std;#define INF0x3f3f3f3fint main() { int n; cin >> n; bitset<1000005> dp, tmp; dp[0] = 1; // 初始状态,表示s=0 for (int i = 1; i <= n; ++i) { int l, r; cin >> l >> r; tmp.reset(); for (int j = l; j <= r; ++j) { tmp |= dp << j * j; } dp = tmp; } int min_sum = dp.bit_count() ? (1LL << 63) : 0; cout << min_sum << endl;}

    详细步骤

  • 初始化Bitsetbitset<1000005> dp, tmp; 创建两个足够大的Bitset来处理可能的平方数。
  • 初始状态dp[0] = 1; 表示初始时,平方数之和为0。
  • 外层循环:遍历$n$个区间。
  • 读取区间:在每个区间内,读取$l$和$r$。
  • 内层循环:遍历区间内的每个$j$,计算$j$的平方。
  • 状态转移tmp |= dp << (j * j); 将新平方数合并到临时状态中。
  • 更新DP状态dp = tmp; 将临时状态更新为新的DP状态。
  • 计算最小总和:最后,dp.bit_count() 统计所有可能平方数的总和最小值。
  • 通过这种方法,我们能够高效地处理每个可能的平方数,并在最终的DP状态中找到最小总和。这种位操作技术减少了内存使用和计算复杂度,使得问题在较大范围内也能高效解决。

    上一篇:物联网信息感知技术笔记
    下一篇:牛客寒假算法基础集训营5 牛牛战队的训练地(三分)

    发表评论

    最新留言

    表示我来过!
    [***.240.166.169]2025年04月15日 15时04分36秒