codeforces597C-树状数组优化dp

因为整个序列为一个1-n的排列,所以可以这样dp dp[i][j]代表长度为i,以数字j结尾的子序列 dp[i][j]=dp[i-1][1,2,3...j-1]; 这道题的答案就是 dp[k+1][1...n];

用树状数组求一下前缀和

 1 #include<bits/stdc++.h>
 2 
 3 #define inf 0x3f3f3f3f
 4 
 5 const int maxn=100000;
 6 
 7 using namespace std;
 8 
 9 typedef long long ll;
10 
11 int n,k;
12 
13 int x;
14 
15 ll dp[15][maxn+10];
16 
17 int lowbit(int x){
18     return x&(-x);
19 }
20 
21 void add(int y,int x,ll val){
22    while(x<=n){
23         dp[y][x]+=val;
24         x+=lowbit(x);
25    }
26 }
27 
28 ll sum(int y,int x){
29    ll res=0;
30    while(x){
31         res+=dp[y][x];
32         x-=lowbit(x);
33    }
34    return res;
35 }
36 
37 int main()
38 {
39     scanf("%d%d",&n,&k);
40     for(int i=1;i<=n;i++){
41         scanf("%d",&x);
42         for(int j=k+1;j>=1;j--){
43                 ll temp=0;
44                 if(j==1){
45                      temp=1;
46                 } else {
47                    temp=sum(j-1,x-1);
48                 }
49                 add(j,x,temp);
50         }
51     }
52     printf("%I64d\n",sum(k+1,n));
53     return 0;
54 }

 

posted @ 2016-10-19 09:41  GeniusYang  阅读(218)  评论(0编辑  收藏  举报