给定一个长度为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); } }
标签:bin,tes,const,int,len,赤壁之战,297,include,acwing From: https://www.cnblogs.com/towboa/p/17178061.html