有$n$种转移装置,每种转移装置本质相同,每种装置可以前进$a_i$单位,但只有$b_i$个。
从初始坐标为$0$出发,途中不能经过$c_1,c2,...,c_m$中的任意一个点。
走到$\sum\limits_{i = 1}^n a_ib_i$位置的方案数$mod 10^9 + 7$的值。
对于$100\%$的数据满足$1 \leq n \leq 6 , 1 \leq m \leq 10^5 ,0<c_i < \sum\limits_{i = 1}^n a_ib_i$
Solution :
由于每个装置本质相同,那么我们只需要记录当前使用的转移装置数作为状态即可。
这样定义状态的总状态数时$\prod_{i = 1}^n b_i \leq 13^6 = 4826809$
注意,由于有$m$点不能走,还需要开一个$hash$存当前值能不能走,特殊判掉即可。
转移的时候枚举当前通过那个转移装置走到当前位置,转移时间复杂度为$O(n)$
请注意,本题的模数为$10^8 + 7$,您是否数错了零?
所以,本题的总时间复杂度是$O(n\prod\limits_{i=1}^{n} b_i)$
# pragma GCC optimize(3) # include<bits/stdc++.h> # define int long long # define hash Hash # define Rint register int using namespace std; const int mo=100000007; int f[13][13][13][13][13][13]; struct rec{int a,b;}a[10]; int n,m; vector<int>hash[10007]; inline int read() { int X=0,w=0; char c=0; while(c<'0'||c>'9') {w|=c=='-';c=getchar();} while(c>='0'&&c<='9') X=(X<<3)+(X<<1)+(c^48),c=getchar(); return w?-X:X; } void insert(int key) { int k = key % 10007,sz = hash[k].size(); for (int i=0;i<sz;i++) if (hash[k][i] == key) return; hash[k].push_back(key); } bool find(int key) { int k=key % 10007,sz = hash[k].size(); for (int i=0;i<sz;i++) if (hash[k][i] == key) return true; return false; } signed main() { n=read(); for (Rint i=1;i<=n;i++) { a[i].a=read(); a[i].b=read(); } m=read(); for (Rint i=1;i<=m;i++) { int t=read(); insert(t); } f[0][0][0][0][0][0]=1; for (Rint a1=0;a1<=a[1].b;a1++) for (Rint a2=0;a2<=a[2].b;a2++) for (Rint a3=0;a3<=a[3].b;a3++) for (Rint a4=0;a4<=a[4].b;a4++) for (Rint a5=0;a5<=a[5].b;a5++) for (Rint a6=0;a6<=a[6].b;a6++) { int tmp = a1*a[1].a+a2*a[2].a+a3*a[3].a+a4*a[4].a+a5*a[5].a+a6*a[6].a; if (find(tmp)) { f[a1][a2][a3][a4][a5][a6]=0; continue; } if (a1+1<=a[1].b) (f[a1+1][a2][a3][a4][a5][a6]+=f[a1][a2][a3][a4][a5][a6])%=mo; if (a2+1<=a[2].b) (f[a1][a2+1][a3][a4][a5][a6]+=f[a1][a2][a3][a4][a5][a6])%=mo; if (a3+1<=a[3].b) (f[a1][a2][a3+1][a4][a5][a6]+=f[a1][a2][a3][a4][a5][a6])%=mo; if (a4+1<=a[4].b) (f[a1][a2][a3][a4+1][a5][a6]+=f[a1][a2][a3][a4][a5][a6])%=mo; if (a5+1<=a[5].b) (f[a1][a2][a3][a4][a5+1][a6]+=f[a1][a2][a3][a4][a5][a6])%=mo; if (a6+1<=a[6].b) (f[a1][a2][a3][a4][a5][a6+1]+=f[a1][a2][a3][a4][a5][a6])%=mo; } printf("%lld\n",f[a[1].b][a[2].b][a[3].b][a[4].b][a[5].b][a[6].b]%mo); return 0; }