dp[i][j]表示以i结尾,长度为j的序列个数
dp[i][j]=dp[k][j-1](k=0.1.....i-1)
用树状数组求和
要注意的一点就是在读入一个数的时候就进行update以及求和,这样保证其后的序列对其无影响。
具体看代码
#include"cstdio" #include"queue" #include"cmath" #include"stack" #include"iostream" #include"algorithm" #include"cstring" #include"queue" #include"vector" #define ll long long using namespace std; const int MAXN = 1e5+50; const int MAXE = 200500; const int INF = 0x3f3f3f; ll dp[MAXN][11]; int lowbit(int x){ return x&-x; } ll sum(int x,int j){ ll tot=0; for(int i=x;i>0;i-=lowbit(i)) tot+=dp[i][j]; return tot; } void update(int x,int j,ll v){ for(int i=x;i<MAXN;i+=lowbit(i)) dp[i][j]+=v; } int main(){ //freopen("in.txt","r",stdin); int n,k;scanf("%d%d",&n,&k);k++; memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++){ ll t,s; scanf("%I64d",&t); update(t,1,1);//dp[t][1]=1; for(int j=2;j<=k;j++){ s=sum(t-1,j-1); update(t,j,s);//dp[t][j]+=s } } ll ans=sum(n,k); printf("%I64d",ans); return 0; }