Codeforces Round 1051 (Div. 2) D1题 题解记录
大致题意:对于一个数组,找出其中有多少个子序列,其不包含严格下降的三个数。比如5,2,3,15,2,3,15,2,3,1,由于包含5,3,15,3,15,3,1或者5,2,15,2,15,2,1,故被视为不合法的。
(这一题或许很简单,但是我脑子转的比较慢,遂记录一下题解)
解:
我们先假设iii位置之前有sss个合法的子序列,现在考虑第iii个位置的数aia_iai。假如从合法的子序列中随便考虑一个ppp,那么首先aia_iai可以不跟随,单独继承ppp;然后aia_iai自己可以单独成为一个新的合法的子序列;然后再考虑aia_iai是否可以接到ppp后面。我们可以发现,aia_iai可以接到ppp后面,当且仅当ppp中所有逆序对(v1,v2)(v_1,v_2)(v1,v2),要求ai≥max(v2)a_i\ge max(v_2)ai≥max(v2)。假如原先有个6,46,46,4,接入一个777,再接入一个666的时候,v2v_2v2发生了变化。之所以会发生变化,是因为其中最大值也发生了变化。故考虑dpdpdp的时候,除了需要存入max(v2)max(v_2)max(v2),也需要考虑最大值。
void solve() {int n;cin >> n;vector<int> a(n + 1);for (int i = 1; i <= n; i++)cin >> a[i];vector<vector<int>> dp(n + 1, vector<int>(n + 1));for (int i = 1; i <= n; i++) {auto ne = dp;for (int j = 1; j <= n; j++) {for (int k = 1; k <= n; k++) {if (a[i] < k)continue;else if (a[i] >= k && a[i] < j) {ne[j][a[i]] = add(ne[j][a[i]], dp[j][k]);} else ne[a[i]][k] = add(ne[a[i]][k], dp[j][k]);}}ne[a[i]][1] = add(ne[a[i]][a[i]], 1);dp = ne;}int s = 1;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)s = add(s, dp[i][j]);cout << s<< endl;
}