给定一个长度为n 的序列 , 求 它有多少个长度为 m的严格递增子序列。
f[i][j] += f[i-1][k] (a[k]<a[i], k<i )
优化 : 维护前缀和,根据a[k]<a[i] ,以a[ ] 为下标维护树状数组 , add(a[i] ,f[i-1][j] )
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std ;
const int N =1e3+4;
const int mod =1e9+7;
#define int long long
int n,m,a[N],f[N][N];
int tr[N];
int bin[N],len;
int lowbit(int x){
return x&-x;
}
void add(int x, int v){
for(; x <= len; x += lowbit(x))
tr[x] = (tr[x]+v),tr[x]%=mod;
}
int qry(int x){
int t=0;
for(;x;x-=lowbit(x)) t+=tr[x],t%=mod;
return t;
}
void solve(int cas){
int i,j;
for(j=2; j<=m;j++) {
for(i=1;i<=len;i++) tr[i] = 0;
for(i=1;i<=n;i++){
f[i][j] =qry(a[i] - 1);
add(a[i], f[i][j-1]);
}
}
int ans=0;
for(int i=1;i<=n;i++) ans+=f[i][m],ans%=mod;
printf("Case #%d: %lld\n",cas,ans);
}
signed main(){
int tes,cas=0;
cin>>tes;
while(tes--){
len=0;
cin>>n>>m;
for(int i = 1; i <= n; i++){
cin>>a[i];
bin[i] = a[i];
f[i][1]=1;
}
sort(bin+1, bin+1+n);
len = unique(bin+1, bin+1+n)-(bin+1);
for(int i = 1; i <= n; i++)
a[i] = lower_bound(bin+1, bin+1+len, a[i]) -bin;
solve(++cas);
}
}
浙公网安备 33010602011771号