TYM 有 nn 本作业,编号为 1,dots,n1,…,n。
由于 mathrm{TYM}TYM 很喜欢偷懒,而且不喜欢消耗脑细胞,所以他选择跳着完成这 nn 本作业。
此外,如果将做作业的顺序转换为 1,dots,n1,…,n 的一个排列,并以序列 ss 表示,有以下规定:
-
最终 forall i in [1,n-1],a_{s_i} leq a_{s_{i+1}}∀i∈[1,n−1],asi≤asi+1。
-
每次做作业时,对于最后一本做完的作业 ii 和下一本准备做的作业 jj,编号为 i,ji,j 之间的作业中,没有做的作业数量 le b_i≤bi。
求满足以上条件的情况下,mathrm{TYM}TYM 做完所有作业的方案数对 49210574921057 取模的结果。
输入输出格式
输入格式:
第一行,一个整数 nn。
第二行,nn 个整数 a_iai。
第三行,nn 个整数 b_ibi。
输出格式:
一行,方案数对 49210574921057 取模的结果。
输入输出样例
输出样例#1:
1
题解:把每个状态压成二进制,进行搜索,搜索下一个满足两个条件的作业,注意,dfs最好只进去一遍,初始化b[0]=maxlongint,所有第一次做的作业会被都搜到(1000,0100,0010,0001);
ps:对于复杂的条件,为了更好理解,建议写在dfs主程序外,独立成函数
1 var 2 n,i,ans:longint; 3 a,b:array[0..500]of longint; 4 function min(x,y:longint):longint; 5 begin 6 if x>y then exit(y) else exit(x); 7 end; 8 function max(x,y:longint):longint; 9 begin 10 if x>y then exit(x) else exit(y); 11 end; 12 13 function pd(l,r,t:longint):longint; 14 var tot:longint; 15 begin 16 tot:=0; 17 for i:=l+1 to r-1 do 18 begin 19 if t and (1<<(i-1))=0 then inc(tot); 20 end; 21 exit(tot); 22 end; 23 procedure dfs(x,t:longint); 24 var i:longint; 25 begin 26 if t=(1<<n)-1 then 27 begin 28 ans:=(ans+1)mod 4921057; 29 exit; 30 end; 31 for i:=1 to n do 32 begin 33 if t and(1<<(i-1))=0 then 34 if (a[i]>=a[x])and(pd(min(i,x),max(i,x),t)<=b[x]) then 35 dfs(i,t+(1<<(i-1))); 36 end; 37 end; 38 begin 39 readln(n); 40 for i:=1 to n do read(a[i]); 41 readln; 42 for i:=1 to n do read(b[i]); 43 {for i:=1 to n do 44 begin 45 46 dfs(i,1<<(i-1)); 47 end;} 48 b[0]:=maxlongint; 49 dfs(0,0); 50 writeln(ans); 51 end.