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 walksb2 more steps on Ox axis and makes a break in point b1 + b2. Similarly, at j-th (1 ≤ j ≤ n) time he walksbj 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).
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 a single integer — the answer of Iahub's dilemma modulo 1000000007 (109 + 7).
3 2 3 5 2 5 7
1
3 2 2 2 2 1 3
6
In the first case consider six possible orderings:
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个数据的位置,使从第一个数累加到第1或者2或3.。。n时,不能让它与k中数的任意一个相等,这算一个正确解。 然后题目要求给出所有正确解的个数,然后mod (1e9+7)。并输出答案。。
题解:
看数据量n这么小。直接建立位映射关系。
00001 表示含有 a1 00010表示含有 a2 ,00101表示a1+a3之类
bitMask[2<<24+1] bitMask[i]=bitMask[i-lowbit(i)]+bitMask[lowbit(i)]
DP方程,i表示选择从1--j中选择i个数字,f[i][j]表示可行解
f[0]=1,表示初始状态.
假如i=1111。分别表示有a1,a2,a3,a4这几个数。则有
容易知道f[1111]=f[1110]+f[1101]+f[1011]+f[0111]
当bitMask[1111]==kk[1]或者kk[0]时,就是不可行的解,就不用计算f[1111]了。
以后在计算f之后的值时也不会重新计算进去。
。。我原先没用DP。结果写出一个超时的程序,后来看了神牛的代码,猛然醒悟好多。。顿时感觉差距还是好大好大的。。。看完后重写了一下
/*
* @author ipqhjjybj
* @date 20130706
*
*/
#include
#include
#include
#define lowbit(x) ((x)&(-x))
#define ll long long
using namespace std;
unsigned int bitMask[1<<24+1],f[1<<24+1];
const int MOD=1e9+7;
int a[26];
int main(){
int n,k,kk[]={-1,0};
int i,j;
scanf("%d",&n);
for(i=0;i
我原先的代码。。。唉。。。在第8个点超时了。。 我用的是先算出总的然后再利用容斥原理,减去不符合的解。。然后超时了,没想到神牛的加法能这么快速。膜拜啊!!
/*
* @author ipqhjjybj
* @date 20130706
*
*/
#include
#include
#include
#include
#define clr(x,k) memset((x),(k),sizeof(x))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MAXN 10000001
#define ll long long
#define MOD 1000000007
#define vi vector
using namespace std;
int a[26],b[3];
int n,k;
ll bitMask[2<<24];
ll jie[27];
int p2[27];
int lowbit(int x){
return x&(-x);
}
ll com(int i){
int j=0;
while(i){
i-=lowbit(i);
j++;
}
return jie[j]*jie[n-j];
}
void linecom(ll &ans,vi &line){
for(vi::iterator it=line.begin();it!=line.end();it++){
ans = (ans-com(*it)+MOD)%MOD;
}
}
int main(){
//freopen("E.in","r",stdin);
int i,j;
for(i=1,jie[0]=1;i<27;i++)
jie[i]=jie[i-1]*i%MOD;
for(i=1;i<27;i++)
p2[i]=1<<(i-1);
while(scanf("%d",&n)!=EOF){
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&k);
for(i=0;i