BZOJ3668 [Noi2014]起床困难综合症

[Solution]

I got WA at the exams, because so stupid I was that I decided to use DP.

In fact, each bit doesn't influence others. We can calculate each bit if it's 1 or 0. Then it's easy  do solve it by first choosing the higher bit.


[Code]

My code on noi2014 day1

#define PROC "sleep"
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <memory.h>
#include <algorithm>
 
using namespace std;
 
struct oper {
    char t;
    int v;
};
 
int nextInt() {
    int d, s = 0;
    do
        d = getchar();
    while (!isdigit(d));
    do
        s = s * 10 + d - 48, d = getchar();
    while (isdigit(d));
    return s;
}
 
const int maxn = 100009;
const int maxl = 30;
 
int n, m, ans, r[maxl + 9][2], a0, f[maxl + 9][2];
oper o[maxn];
 
int getAns(int x) {
    for (int i = 0; i < n; i ++)
        switch (o[i]. t) {
            case 'A':
                x &= o[i]. v;
                break;
            case 'O':
                x |= o[i]. v;
                break;
            case 'X':
                x ^= o[i]. v;
                break;
        }
    return x;
}
 
void dp() {
    memset(f, 0, sizeof(f));
    if (m & (1 << maxl)) {
        f[maxl][1] = r[maxl][1];
        f[maxl][0] = r[maxl][0];
    }
    else {
        f[maxl][1] = r[maxl][0];
        f[maxl][0] = -1;
    }
    for (int i = maxl; i > 0; i --) 
        if (m & (1 << (i - 1))) {
            f[i - 1][0] = f[i][1] + r[i - 1][0];
            if (f[i][0] > -1)
                f[i - 1][0] = max(f[i][0] + max(r[i - 1][1], r[i - 1][0]), f[i - 1][0]);
            f[i - 1][1] = f[i][1] + r[i - 1][1];
        }
        else {
            if (f[i][0] > -1)
                f[i - 1][0] = f[i][0] + max(r[i - 1][1], r[i - 1][0]);
            else
                f[i - 1][0] = -1 ;
            f[i - 1][1] = f[i][1] + r[i - 1][0];
        }
}           
 
int main() {
    ans = 0;
    n = nextInt();
    m = nextInt();
    for (int i = 0; i < n; i ++) {
        char opt[10];
        scanf("\n%s", opt);
        o[i]. t = opt[0];
        o[i]. v = nextInt();
    }
    a0 = getAns(0);
    for (int i = 0; i <= maxl; i ++) {
        r[i][0] = (a0 & (1 << i));
        r[i][1] = (getAns(1 << i) & (1 << i));
    }
    dp();
    printf("%d\n", max(f[0][0], f[0][1]));
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值