P2396-yyylovesMathsVII【状压dp】

正题

题目链接:https://www.luogu.com.cn/problem/P2396


题目大意

n n 个数字,依次选择若干个数字使得没有任何一个前缀和等于厄运数字,厄运数字有 m m 个。


解题思路

先预处理出 d i s i dis_i 表示集合 i i 的数字和。

然后对于 d i s i dis_i 不等于厄运数字有转移 f i = 2 j i f 2 j f_{i}=\sum_{2^j\in i}f_{2^j}

需要卡卡常就好了


#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]);
}
发布了867 篇原创文章 · 获赞 55 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/Mr_wuyongcong/article/details/104081889