• uestc oj 1217 The Battle of Chibi (dp + 离散化 + 树状数组)


    题目链接:http://acm.uestc.edu.cn/#/problem/show/1217

    给你一个长为n的数组,问你有多少个长度严格为m的上升子序列。

    dp[i][j]表示以a[i]结尾长为j的上升子序列个数。常规是三个for。

    这里用树状数组优化一下,类似前缀和的处理,两个for就好了。

     1 //#pragma comment(linker, "/STACK:102400000, 102400000")
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <ctime>
    10 #include <list>
    11 #include <set>
    12 #include <map>
    13 using namespace std;
    14 typedef long long LL;
    15 typedef pair <int, int> P;
    16 const int N = 1e3 + 5;
    17 LL dp[N][N], mod = 1e9 + 7;
    18 int a[N], b[N], m, n;
    19 LL bit[N][N];
    20 
    21 void add(int pos, int i, int val) { //上升子序列长度为pos 
    22     for( ; i <= n; i += (i&-i))
    23         bit[pos][i] = (bit[pos][i] + val) % mod;
    24 }
    25 
    26 LL sum(int pos, int i) {
    27     LL s = 0;
    28     for( ; i >= 1; i -= (i&-i))
    29         s = (s + bit[pos][i]) % mod;
    30     return s;
    31 }
    32 
    33 int main()
    34 {
    35     int t;
    36     scanf("%d", &t);
    37     for(int ca = 1; ca <= t; ++ca) {
    38         scanf("%d %d", &n, &m);
    39         for(int i = 1; i <= n; ++i) {
    40             scanf("%d", a + i);
    41             b[i] = a[i];
    42         }
    43         sort(b + 1, b + n + 1);
    44         for(int i = 1; i <= n; ++i) {
    45             a[i] = lower_bound(b + 1, b + n + 1, a[i]) - b; //离散化
    46         }
    47         memset(dp, 0, sizeof(dp));
    48         memset(bit, 0, sizeof(bit));
    49         dp[1][1] = 1;
    50         add(1, a[1], 1);
    51         for(int i = 2; i <= n; ++i) {
    52             dp[i][1] = 1;
    53             for(int k = max(m - (n - i), 1); k <= min(i, m); ++k) { //这边可以优化一下
    54                 dp[i][k] = (dp[i][k] + sum(k - 1, a[i] - 1)) % mod; //比a[i]小且上升子序列长度为k-1
    55                 add(k, a[i], dp[i][k]);
    56             }
    57         }
    58         LL res = 0;
    59         for(int i = 1; i <= n; ++i) {
    60             res = (res + dp[i][m]) % mod;
    61         }
    62         printf("Case #%d: %lld
    ", ca, res);
    63     }
    64     return 0; 
    65 }
  • 相关阅读:
    深入理解网卡配置bond的意义和作用
    关于B站UP主墨茶official逝世的感想
    Python内置函数学习笔记
    Python学习笔记(4)
    测试工作中不可忽略的点
    Python学习笔记(3)
    Python学习笔记(2)
    Python学习笔记(1)
    docker-compose部署
    Xtrabackup源码安装
  • 原文地址:https://www.cnblogs.com/Recoder/p/5901354.html
Copyright © 2020-2023  润新知