子序列(牛客4.24 dp)

子序列

题目链接
题解链接

题目描述
小美有一个由 n n 个元素组成的序列 { a 1 , a 2 , a 3 , . . . , a n } \{a_1,a_2,a_3,...,a_n\} ,她想知道其中有多少个子序列 { a p 1 , a p 2 , . . . , a p m } ( 1 m n , 1 p 1 < p 2 , . . . , < p m n ) \{a_{p_1},a_{p_2},...,a_{p_m}\} (1 \le m \le n, 1 \le p_1 < p_2 ,..., < p_m ≤ n) ,满足对于所有的 i , j ( 1 i < j m ) i,j(1 \le i < j \le m) , a p i p j < a p j p i {a_{p_i}}^{p_j} < {a_{p_j}}^{p_i} 成立。
输入描述:
第一行一个整数 n ( 1 n 100 ) n (1≤n≤100) 表示序列长度。
接下来一行n个整数 { a 1 , a 2 , a 3 , . . . , a n } ( 1 a i 100 ) \{a_1,a_2,a_3,...,a_n\}(1≤a_i≤100) 表示序列。
输出描述:
输出一行表示满足条件的子序列的数目。因为答案可能很大,请输出答案 mod 1e9+7。
示例1
输入

2
1 2
输出
3
说明
满足条件的子序列为 { 1 } , { 2 } , { 1 , 2 } \{1\}, \{2\}, \{1,2\}

分析:
如果满足 a x y < a y x , a y z < a z y {a_x}^y < {a_y}^x , {a_y}^z < {a_z}^y ,那么 a x z < a z x {a_x}^z < {a_z}^x 也成立。
因为: a x z = ( a x y y ) z < ( a y x y ) z = ( a y z y ) x < ( a z y y ) x = a z x {a_x}^z = (\sqrt[y]{{a_x}^y})^z < (\sqrt[y]{{a_y}^x})^z = (\sqrt[y]{{a_y}^z})^x < (\sqrt[y]{{a_z}^y})^x = a_z^x
以上证得传递性。对判断条件 i < j i<j a i j < a j i {a_{i}}^{j} < {a_{j}}^{i} ,数太大,可以取对数把指数拿下来变成 j log a i < i log a j j\log{a_{i}} < i\log{a_{j}} 也成立。
d p i dp_i 表示以 a i a_i 结尾的符合条件的子序列的个数,结果就是 d p i \sum dp_i

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int N = 100 + 5;
int n;
int a[N];
ll dp[N]; //dp[i]表示必须以a[i]结尾的可行的子序列的个数
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        dp[i] = 1;
    }
    ll ans = 0;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j < i; j++)
        {
            if (j * log(a[i]) > i * log(a[j]))
            {
                dp[i] = (dp[i] + dp[j]) % mod;
            }
        }
        ans = (ans + dp[i]) % mod;
    }
    cout << ans << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44169557/article/details/106043140