C - Hasan and his lazy students
题意: 给出n个序列,求最长的严格单调递增子序列的数目。(
1
≤
n
≤
1000
1\leq n \leq 1000
1≤n≤1000, 对结果取模
1
e
9
+
7
1e9 + 7
1e9+7)
思路:
需要先熟悉最长当单调子序列的dp求法。由数据范围可知,大概是个dp。这道题其实是用了两个一维dp数组。
dp[i]表示以第i个数结尾的最长单调递增子序列的长度
sum[i]表示前i个数中长度等于dp[i]的序列个数
代码:
const int N = 2e5 + 7, M = 1e6;
int a[1007];
int dp[1007], sum[1007], mod = 1000000007;
//dp[i]表示以第i个数结尾的最长单调子序列的长度
//sum[i]表示前i个数中长度等于dp[i]的序列个数
int main()
{
IOS;
int T; cin >> T;
while (T--)
{
int n; cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
int maxn = 0, ans = 0;
for (int i = 1; i <= n; i++)
{
dp[i] = 1; sum[i] = 1;
//二者都不能删,第一个删掉会导致dp[i] = 0(如果a[i]前面没有比a[i]小的)
//第二个删掉会导致全程sum都是0
for (int j = 1; j < i; j++)
if (a[j] < a[i])
{
if (dp[j] + 1 > dp[i])
dp[i] = dp[j] + 1, sum[i] = sum[j];
else if (dp[j] + 1 == dp[i])
sum[i] = (sum[i] + sum[j]) % mod;
}
if (dp[i] > maxn) maxn = dp[i], ans = sum[i];
else if (dp[i] == maxn) ans = (ans + sum[i]) % mod;
}
cout << maxn << " " << ans << endl;
}
return 0;
}