hdu6140 bitset

来源:互联网 发布:深圳旅游知乎 编辑:程序博客网 时间:2024/06/03 12:07

Problem H

给出数列 a1na1…n。求能否从中挑出一些数累加得到 kk。 

数据范围:103ai103,1n103,k106−103≤ai≤103,1≤n≤103,‖k‖≤106。 

Solution

利用 bitsetbitset 记录能够到达的值:每加入一个数xx,将原来的 bitsetbitset 左移或者右移 xx 位然后再与原 bitsetbitset 或运算得到新的 bitsetbitset,位移运算相当于将xx 累加到了原来能够到达的所有值上,或运算相当于将新得到的值与原来的值合并在一块。


#include<iostream>
#include<cstdio>
#include<bitset>
using namespace std;
const int MaxN=1005;
const int MaxM=1000005;
int T, n, k, a[MaxN];char b[MaxN];
bitset<MaxM> Right, Left;void solve(){    int rmax = 0, lmax = 0;    for(int i=1;i<=n;i++)        switch(b[i])        {        case 'N':            rmax+=a[i];            lmax+=a[i];            break;        case 'D':            lmax+=a[i];            break;        case 'L':            rmax+=a[i];        }    if( (k>0 && rmax<k) || (k<0 && lmax<-k) ) puts("no");    else    {        for(int i=1;i<=n;i++)        {            switch(b[i])            {            case 'N':                Right |= (Right<<a[i]);                Left  |= (Left <<a[i]);                break;            case 'D':                Left  |= (Left <<a[i]);                break;            case 'L':                Right |= (Right<<a[i]);            }        }        if(k==0 ||  (k>0 && Right.test(k)) || (k<0 && Left.test(-k)) ) puts("yes");        else         {            bool flag = false;            for(int i=k+1;i<=1E6;i++)            {                if(k>0)                {                    if(Right.test(i) && Left.test(i-k))                     {                        flag = true;                        break;                    }                }                else                {                    if(Left.test(i) && Right.test(i+k))                     {                        flag = true;                        break;                    }                }            }            if(flag) puts("yes");            else puts("no");        }    }}int main(){    scanf("%d",&T);    while(T--)    {        cin>>n;cin>>k;        Left.reset();        Right.reset();        Left.set(0);        Right.set(0);        for(int i=1;i<=n;i++) cin>>a[i];        for(int i=1;i<=n;i++) scanf(" %c", &b[i]);        solve();    }}


原创粉丝点击