1454. 异或和是质数的子集数 01背包
题意
给出 n 个互不相同的正整数。
问存在多少个子集,使得子集中所有数的异或和是质数。
由于答案可能很大,请你输出对 109+7 取模后的结果。
分析
题意就是指:
从一堆元素中挑选元素,达到指定的要求的题目,符合01背包的性质。使用01背包即可
求背包大小:
由于数据范围最大不超过5000, 异或是二进制运算,, 所以即使是异或后的数,它的二进制表示不超过13位。
代码
#include <bits/stdc++.h> using namespace std; #define int long long #define pii pair<int, int> const int N =5010,M=1e9+7; const int MAX=8192; int n; int a[N]; int dp[3][MAX]; bool is_prime(int x){ if(x<2) return false; for(int i=2;i<=x/i;i++){ if(x%i==0) return false; } return true; } void slove() { cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } // dp数组初始化,即没有数字可选,但是要达到异或和为0,正好有1种选法:即什么都不选。 dp[0][0]=1; for(int i=1;i<=n;i++){ for(int j=0;j<MAX;j++){ dp[i&1][j]=dp[(i-1)&1][j]; if( (j^a[i]) < MAX){ dp[i&1][j]+=dp[(i-1)&1][j^a[i]]; } dp[i&1][j]%=M; } } int ans=0; for(int i=2;i<MAX;i++){ if(is_prime(i)){ ans=(ans+dp[n&1][i])%M; } } cout<<ans<<endl; } signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t = 1; // cin >> t; while (t--) slove(); return 0; }
本文作者:kingwzun
本文链接:https://www.cnblogs.com/kingwz/p/16651483.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2021-09-02 Java基础语法