题解:
- 首先,我们把问题拆分。假设这是一道不那么复杂,数据普通的子序列问题。
- 则对于一个数,结果中所有包含它的序列都是从前面的序列中继承过来的。那么到这个数为止,它能产生的新的序列就是1+它之前所有比较结果成立的序列数如果用 f[i] 来记录第i个数产生的新序列,那么转换方程就是1+sum{1,i-1}f[i]。
- 解决了状态转移方程的问题,接下来就是怎么把比较时的 a[i]^j 和 a[j]^i 实现的问题。
- 而对于这种指数问题,我们通常可以想到的方法就是取对数,于是我们将它们取以10为底的对数,化简就可以得到: j*log10(a[i]) 和 i*log10(a[j]) ,那为了不每次比较都算一遍,我们可以对它进行移项操作,得到log(a[i])/i,这样,我们就把每个数的权值算出来了,而且经过取对数,数据也比较小,可以直接比较!
标程:
#include<iostream>
#include<cmath>
using namespace std;
const int mod=1000000007;
int a[110],f[110];
double s[110];
bool judge(int i,int j){
if(s[j]<s[i])
return true;
else return false;
}
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)//权值计算
s[i]=log(a[i])/i;
for(int i=1;i<=n;i++){//状态转移
f[i]=1;
for(int j=1;j<=i;j++){
if(judge(i,j)){
f[i]+=f[j];
f[i]%=mod;
}
}
}
long long res=0;
for(int i=1;i<=n;i++){
res+=f[i];
res%=mod;//记得每次计算后都要取模哦!
}
cout<<res<<endl;
return 0;
}