Solved:1
rank:249
E. Removal
dp i,j表示前i个数删除了j个且选择了第i个的答案
类似字符串的dp 预处理一下nex i_k即i后面k第一次出现的位置 就好转移了
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod = 1e9 + 7; int s[100005]; int nex[100005][12]; int now[12]; ll dp[100005][12]; int main() { int n, m, kk; while(~scanf("%d%d%d", &n, &m, &kk)) { memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) scanf("%lld", &s[i]); for(int i = 1; i <= kk; i++) now[i] = n + 1; for(int i = n; i >= 0; i--) { for(int j = 1; j <= kk; j++) nex[i][j] = now[j]; now[s[i]] = i; } dp[0][0] = 1; //dp[0][0] = 1; for(int i = 0; i <= n; i++) { for(int j = 0; j <= m; j++) { if(!dp[i][j]) continue; for(int k = 1; k <= kk; k++) { int t = nex[i][k]; if(t == n + 1) continue; if(t - i + j - 1 > m) continue; (dp[t][t - i + j - 1] += dp[i][j]) %= mod; } } } ll ans = 0; for(int i = 1; i <= n; i++) if(i - n + m >= 0) (ans += dp[i][i - n + m]) %= mod; printf("%lld ", ans); } return 0; }