2019哈尔滨理工大学校赛B题 状态压缩dp

喜你入骨 提交于 2019-12-09 19:34:28

2019哈尔滨理工大学校赛B题 状态压缩dp

题目描述:

在这里插入图片描述
非常有意思的题,比赛中是队友过的,题目意思是如上。

解题思路

把所有存在a[i]使其&为0的值标记,再依次判断a[i]是否被标记,实现如下:初始化把所有a[i]^11111…111(二进制)的值k标记为1,即k&a[i]必为0。此时二进制下的k存在a[i]使其&为0,则我们可以在k的基础上,一步步把他二进制中的1一个一个去掉的值标记,去掉后的值也肯定存在a[i]使其&为0。详情看代码:

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
const ll maxn=(1<<20)-1;
ll a[maxn+5],dp[maxn+5];
int main(){
    ll n;
    while(scanf("%lld",&n)==1){
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            dp[maxn^a[i]]=1;
        }
        for(int i=maxn;i>=1;i--){
            if(dp[i]){//每个数只减一个1,减完后的数下次遍历到会继续减
                for(int j=0;j<=20;j++){
                    if(i&(1<<j)){
                        dp[i^(1<<j)]=1;
                    }
                }
            }
        }
        for(int i=1;i<=n;i++){
            if(dp[a[i]]) printf("YES\n");
            else printf("NO\n");
        }
    }
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!