OJ題目:click here~~
題目分析:1e6的約數很大 , 但是個數確很少,不到60個。所以狀態可以簡化為dp[ i ][ j ] , j為約束的id 。
AC_CODE
const int mod = 1000000007; vectorList[2001]; int num[2008]; int dp[2008][60]; int n , k , ans = 0; map mp; inline int gcd(int x , int y){ return y == 0 ? x : gcd(y , x%y); } inline LL lcm(int x , int y){ return (LL)x / gcd(x , y) * y; } int dfs(int u , int score){ int id = mp[score]; if(dp[u][id] != -1) return dp[u][id]; LL ret = 0; for(int i = 0;i < List[u].size();i++){ int v = List[u][i]; LL LCM = lcm(score , num[v]); if(k%LCM ||LCM == score) continue; ret += dfs(v , LCM) , ret %= mod; } return dp[u][id] = ret; } int main() { int m , k , i , j , a, b ; while(scanf("%d%d%d",&n,&m,&k) != EOF){ for(i = 0;i <= n;i++) List[i].clear(); for(i = 0;i < m;i++){ scanf("%d%d",&a,&b) ; List[a].push_back(b) ; } for(i = 1;i <= n;i++) scanf("%d",&num[i]) ; if(k%num[n]){ puts("0") ; } else { List[0].push_back(1); int id = 0 ; mp.clear() ; for(i = 1;i * i <= k;i++){ if(k%i == 0){ mp[i] = id++ ; mp[k/i] = id++ ; } } memset(dp , -1 , sizeof(dp)) ; dp[n][mp[k]] = 1; cout << dfs(1 , num[1]) << endl; } } return 0; }