output
standard output
Iahub wants to meet his girlfriend Iahubina. They both live in Ox axis (the horizontal axis). Iahub lives at point 0 and Iahubina at point d.
Iahub has n positive integers a1, a2, ..., an. The sum of those numbers is d. Suppose p1, p2, ..., pn is a permutation of {1, 2, ..., n}. Then, let b1 = ap1, b2 = ap2 and so on. The array b is called a "route". There are n! different routes, one for each permutation p.
Iahub's travel schedule is: he walks b1 steps on Ox axis, then he makes a break in point b1. Then, he walks b2 more steps on Ox axis and makes a break in point b1 + b2. Similarly, at j-th (1 ≤ j ≤ n) time he walks bj more steps on Ox axis and makes a break in point b1 + b2 + ... + bj.
Iahub is very superstitious and has k integers which give him bad luck. He calls a route "good" if he never makes a break in a point corresponding to one of those k numbers. For his own curiosity, answer how many good routes he can make, modulo 1000000007(109 + 7).
Input
The first line contains an integer n (1 ≤ n ≤ 24). The following line contains n integers: a1, a2, ..., an (1 ≤ ai ≤ 109).
The third line contains integer k (0 ≤ k ≤ 2). The fourth line contains k positive integers, representing the numbers that give Iahub bad luck. Each of these numbers does not exceed 109.
Output
Output a single integer — the answer of Iahub's dilemma modulo 1000000007 (109 + 7).
Examples
input
Copy
3 2 3 5 2 5 7output
Copy
1input
Copy
3 2 2 2 2 1 3output
Copy
6Note
In the first case consider six possible orderings:
- [2, 3, 5]. Iahub will stop at position 2, 5 and 10. Among them, 5 is bad luck for him.
- [2, 5, 3]. Iahub will stop at position 2, 7 and 10. Among them, 7 is bad luck for him.
- [3, 2, 5]. He will stop at the unlucky 5.
- [3, 5, 2]. This is a valid ordering.
- [5, 2, 3]. He got unlucky twice (5 and 7).
- [5, 3, 2]. Iahub would reject, as it sends him to position 5.
In the second case, note that it is possible that two different ways have the identical set of stopping. In fact, all six possible ways have the same stops: [2, 4, 6], so there's no bad luck for Iahub.
题意 :给n个数的一个序列n<=24再给出k个序列k<=2问n个数的全排列中前缀和不出现给的这k个数中的任意一个的排列种数有多少种, 一开始想到阶乘的种数上去了后来看题解是二进制状态压缩枚举出现的次数然后暴力的。
首先二进制暴力的时候位为1表示出现过了然后用一个数组来表示前缀和通过判断这个数组和K个数是否相等来判断是否要更新计数的数组。更新的方法为把当前所有位为1的数分别当做最后一位进行累加比如111就通过110,101,011这三个状态转移过来因为是从小到大枚举嘛前面的状态肯定也是这样过来的不会漏掉,如果说前置状态存在K里的某一种情况那么dp之前肯定也不会操作他那他就是0也就是没记录他
#include <iostream>
#include <cstdio>
#include <set>
#include <map>
#include <algorithm>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
const long long int inf=1e9+7;
long long int dp[1<<24],dp1[1<<24];
int d[3];
long long lowbit(int x){
return x&(-x);
}
int main(){
int n;
while(~scanf("%d",&n)){
memset(dp1,0,sizeof(dp1));
for(int i=0;i<n;i++){
int x;
cin>>x;
dp1[1<<i]=x;
}
int k;
scanf("%d",&k);
for(int i=1;i<=k;i++){
scanf("%d",&d[i]);
}
long long ans=1<<n;
dp[0]=1;
for(long long i=1;i<ans;i++){
dp1[i]=dp1[i-lowbit(i)]+dp1[lowbit(i)];
if(dp1[i]==d[1]||dp1[i]==d[2])
continue;
for(long long j=i;j;j-=lowbit(j)){
long long k=i-lowbit(j);
dp[i]+=dp[k];
if(dp[i]>inf)
dp[i]-=inf;
}
}
cout<<dp[ans-1]<<endl;
}
}