【每日一题】子序列
子序列
https://ac.nowcoder.com/acm/problem/17065
solution
我们大胆猜测:如果当前已经选择了一些位置,加入新位置时只要与已选的最后一个位置满足题目条件,那么肯定与前面的每个位置都满足条件。
下面给出证明。
证明:设已有。对于第一个不等式,同时变为,因为底数为正数,所以不等式符号不变。即变为,对于第二个不等式,同时变为,即变为。然后将这两个新的不等式合并得到,同样的,我们让两边同时变为,得到。
然后就变成了一个比较简单的了,用表示已第个位置结尾符合条件的子序列个数。转移只要枚举一个满足的,让即可。
还有最后一个问题,如何比较与的大小。我们对其同时取对数,即比较与的大小。根据高中所学,我们知道,所以只要比较与的大小就行了。
code
/* * @Author: wxyww * @Date: 2020-04-23 18:58:23 * @Last Modified time: 2020-04-23 19:03:03 */ #include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<algorithm> #include<queue> #include<vector> #include<ctime> using namespace std; typedef long long ll; const int N = 110,mod = 1e9 + 7; ll read() { ll x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); } return x * f; } int f[N],a[N]; int main() { int n = read(); for(int i = 1;i <= n;++i) a[i] = read(); f[0] = a[0] = 1; ll ans = 0; for(int i = 1;i <= n;++i) { f[i] = 1; for(int j = 1;j < i;++j) { if(i * log(a[j]) < j * log(a[i])) f[i] += f[j],f[i] %= mod; } ans += f[i]; ans %= mod; } cout<<ans<<endl; return 0; }