C - The Battle of Chibi 树状数组+暴力DP

https://blog.csdn.net/loy_184548/article/details/50073559

 1 #include <vector>
 2 #include <map>
 3 #include <set>
 4 #include <algorithm>
 5 #include <iostream>
 6 #include <cstdio>
 7 #include <cmath>
 8 #include <cstdlib>
 9 #include <string>
10 #include <cstring>
11 using namespace std;
12 #define MOD 1000000007
13 #define  lowbit(x)  ((x) & -(x))
14 int num[1010];
15 int dp[1010][1010];
16 int b[1010];
17 int n,m;
18 int sum(int x,int y)   //计算y长度的子序列,前x项有多少种情况的和
19 {
20     int ret = 0;
21     while(x > 0)
22     {
23         ret = (ret + dp[x][y]) % MOD;
24         x -= lowbit(x);
25     }
26     return ret;
27 }
28 void add(int x,int y,int d)  //更新x及以上长度,能取到的y的值为d
29 {
30     while(x <= n)
31     {
32         dp[x][y] = (dp[x][y] + d) % MOD;
33         x += lowbit(x);
34     }
35 }
36 int main(){
37     int t;
38     scanf("%d",&t);
39     int cnt = 1;
40     while(t--)
41     {
42 
43         scanf("%d%d",&n,&m);
44         memset(dp,0,sizeof(dp));
45         for (int i = 1; i <= n; i++)
46         {
47             scanf("%d",&num[i]);
48             b[i] = num[i];
49         }
50         sort(b + 1,b + 1 + n);
51         for (int i = 1; i<= n; i++)
52         {
53             num[i] = lower_bound(b + 1, b + 1 + n, num[i]) - b;  //num[i]存储的是该位置是第几大的元素
54         }
55         for(int i=1;i<=n;i++)
56             printf("%d ",b[i]);
57         printf("\n");
58         for(int i=1;i<=n;i++)
59             printf("%d ",num[i]);
60         printf("\n");
61         for (int i = 1; i <= n; i++)
62         {
63             for (int j = 1; j <= min(i+1,m); j++)
64             {
65                 if (j == 1) add(num[i],1,1);
66                 else{
67                     int temp = sum(num[i] - 1,j - 1);
68                     add(num[i],j,temp);
69                 }
70             }
71         }
72         printf("Case #%d: %d\n",cnt++,sum(n,m));
73     }
74     return 0;
75 }

 

posted @ 2020-10-05 22:14  古比  阅读(139)  评论(0编辑  收藏  举报