solution
n 个 数 , a n s 个 填 − 1 的 位 置 , r e s 个 已 有 数 字 且 该 数 字 原 位 置 为 − 1 的 位 置 ( 万 能 ) n个数,ans个填-1的位置,res个已有数字且该数字原位置为-1的位置(万能) n个数,ans个填−1的位置,res个已有数字且该数字原位置为−1的位置(万能)
传 统 错 排 : d p [ i ] = ( i − 1 ) ( d p [ i − 1 ] + d p [ i − 2 ] ) 传统错排:dp[i] = (i -1)(dp[i-1]+dp[i-2]) 传统错排:dp[i]=(i−1)(dp[i−1]+dp[i−2])
额 外 考 虑 万 能 的 数 字 : d p [ i ] + = d p [ i − 1 ] ∗ r e s 额外考虑万能的数字:dp[i]+=dp[i-1]*res 额外考虑万能的数字:dp[i]+=dp[i−1]∗res
code
/*SiberianSquirrel*/
/*CuteKiloFish*/
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<int>;
using vll = vector<ll>;
const ll MOD = ll(1e9 + 7);
ll a[2010], dp[2010];
void solve() {
int n; cin >> n;
int ans = 0, res = 0; dp[0] = 1;
for (int i = 1; i <= n; ++ i) {
cin >> a[i]; dp[i] = 0;
if(a[i] == -1) ans ++;
}
for (int i = 1; i <= n; ++ i) {
if(a[i] != -1) {
if(a[a[i]] == -1) res ++;
}
}
int x = ans - res;
for (auto i = 2; i <= res; ++ i) {
dp[0] = dp[0] * i % MOD;
}
for (auto i = 1; i <= ans; ++ i) {
dp[i] = (dp[i] + dp[i - 1] * (i - 1 + res) % MOD) % MOD;
if(i != 1) dp[i] = (dp[i] + dp[i - 2] * (i - 1) % MOD) % MOD;
}
cout << dp[x] % MOD << endl;
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
signed test_index_for_debug = 1;
char acm_local_for_debug = 0;
do {
if (acm_local_for_debug == '$') exit(0);
if (test_index_for_debug > 20)
throw runtime_error("Check the stdin!!!");
auto start_clock_for_debug = clock();
solve();
auto end_clock_for_debug = clock();
cout << "Test " << test_index_for_debug << " successful" << endl;
cerr << "Test " << test_index_for_debug++ << " Run Time: "
<< double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
cout << "--------------------------------------------------" << endl;
} while (cin >> acm_local_for_debug && cin.putback(acm_local_for_debug));
#else
solve();
#endif
return 0;
}