正题
题目链接:https://www.luogu.com.cn/problem/P2396
题目大意
nnn个数字,依次选择若干个数字使得没有任何一个前缀和等于厄运数字,厄运数字有mmm个。
解题思路
先预处理出disidis_idisi表示集合iii的数字和。
然后对于disidis_idisi不等于厄运数字有转移fi=∑2j∈if2jf_{i}=\sum_{2^j\in i}f_{2^j}fi=2j∈i∑f2j
需要卡卡常就好了
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=24,XJQ=1e9+7;
int n,m,MS,lim1,lim2,f[1<<N],dis[1<<N];
int main()
{scanf("%d",&n);for(int i=0;i<n;i++)scanf("%d",&dis[1<<i]);scanf("%d",&m);if(m>0) scanf("%d",&lim1);if(m>1) scanf("%d",&lim2);MS=1<<n;f[0]=1;for(int i=0;i<MS;i++){int j=i&-i;dis[i]=dis[i^j]+dis[j];if(dis[i]==lim1||dis[i]==lim2) continue;int k=i;while(k){j=k&-k;f[i]=f[i]+f[i^j];if(f[i]>=XJQ)f[i]-=XJQ;k^=j;}}printf("%d",f[MS-1]);
}