[洛谷P2114] [NOI2014]起床困难综合症

本文介绍了一种利用位运算和状态压缩动态规划(状压DP)解决特定类型数学问题的方法。通过分析题目需求,运用二进制位运算特性,实现参数的独立处理,进而采用类似贪心策略,计算出最优化结果。文章提供了详细的算法思路和C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题传送门

此题的思想还是位运算&状压DP

位运算的特点是二进制下不进位,故参与位运算的各位之间是相互独立的

X0的第k位应该填为1仅当在下面两种情况时出现:

  1. 已有数值+1<<k不超过m
  2. 用每个参数的第k位参与运算,若初值为1,那么经过n次操作后结果为1,0时同理

这样,我们就可以用类似于贪心的思想,得到尽可能大的结果

直接大力设结果,爆算每一位。。

Code:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 100010;
int n, m, x;
pair<string, int> a[maxn];
inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (!isdigit(ch))
        f = (ch == '-') ? -1 : 1, ch = getchar();
    while (isdigit(ch))
        x = x * 10 + (ch - '0'), ch = getchar();
    return x * f;
}
inline int cal(int bit, int now)
{
    for (int i = 1; i <= n; i++)
    {
        int x = a[i].second >> bit & 1;
        if (a[i].first == "AND")
            now &= x;
        else if (a[i].first == "OR")
            now |= x;
        else
            now ^= x;
    }
    return now;
}
signed main()
{
    n = read(), m = read();
    for (int i = 1; i <= n; i++)
    {
        char str[5];
        int x;
        scanf("%s%d", str, &x);
        a[i] = make_pair(str, x);
    }
    int val = 0, ans = 0;
    for (int bit = 29; bit >= 0; bit--)
    {
        int res0 = cal(bit, 0);
        int res1 = cal(bit, 1);
        if (val + (1 << bit) <= m && res0 < res1)
            val += 1 << bit, ans += res1 << bit;
        else
            ans += res0 << bit;
    }
    cout << ans << '\n';
}

转载于:https://www.cnblogs.com/wyctstf/p/11519394.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值