DP+BIT(优化复杂度) UESTC 1217 The Battle of Chibi

题目传送门

题意:问n长度的序列,找出长度m的上升子序列的方案数。

分析:这个问题就是问:dp[i][j] = sum (dp[i-1][k]) (1 <= k <= n, a[k] < a[j]),当前长度i一层,最后下标j一层,之前的最后下标k一层,这样是n^3的复杂度。然后树状数组可以优化j,k的复杂度,就是j扫描一遍的同时,将a[j]的信息更新到树上,那么扫描就可以用 logn时间统计出k的信息,在这之前先对a[]离散化。

/************************************************
* Author        :Running_Time
* Created Time  :2015/10/21 星期三 13:20:36
* File Name     :C.cpp
 ************************************************/

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e3 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-8;
struct BIT  {
    int c[N], SZ;
    void add(int &a, int b) {
        a += b;
        while (a >= MOD)    a -= MOD;
    }
    void init(int n)    {
        memset (c, 0, sizeof (c));
        SZ = n;
    }
    void updata(int i, int x)   {
        while (i <= SZ) {
            add (c[i], x);  i += i & (-i);
        }
    }
    int query(int i)    {
        int ret = 0;
        while (i)   {
            add (ret, c[i]);    i -= i & (-i);
        }
        return ret;
    }
}bit;
int a[N], A[N];
int dp[N][N];

void compress(int n) {
    sort (A, A+n);
    int nn = unique (A, A+n) - A;
    for (int i=0; i<n; ++i)    {
        a[i] = lower_bound (A, A+n, a[i]) - A + 1;
    }
}

int main(void)    {
    int T, cas = 0; scanf ("%d", &T);
    while (T--) {
        int n, m;  scanf ("%d%d", &n, &m);
        bit.init (n);
        for (int i=0; i<n; ++i)    {
            scanf ("%d", &a[i]);
            A[i] = a[i];
        }
        compress (n);
        memset (dp, 0, sizeof (dp));
        for (int i=0; i<n; ++i) dp[1][i] = 1;
        int ans = 0;
        for (int i=2; i<=m; ++i)    {
            bit.init (n);
            for (int j=0; j<n; ++j) {
                dp[i][j] = bit.query (a[j] - 1);
                bit.updata (a[j], dp[i-1][j]);
            }
        }
        for (int i=0; i<n; ++i) bit.add(ans, dp[m][i]);
        printf ("Case #%d: %d\n", ++cas, ans);
    }

    return 0;
}

  

时间: 2024-10-26 21:58:50

DP+BIT(优化复杂度) UESTC 1217 The Battle of Chibi的相关文章

UESTC 1217 The Battle of Chibi

dp+树状数组优化. dp[i][j]表示以a[i]结尾,最长上升序列长度为j的方案数.dp[i][j]=sum{dp[k][j-1]} 其中k<i&&a[k]<a[i]. 离散化后,可以用1000个树状数组维护. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath>

CDOJ 1217 The Battle of Chibi

The Battle of Chibi Time Limit: 6000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Cao Cao made up a big army and was going to invade the whole South China. Yu Zhou was worried about it. He thought the only way to beat Cao Cao is

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 #incl

学渣乱搞系列之dp斜率优化

学渣乱搞系列之dp斜率优化 By 狂徒归来 貌似dp的斜率优化一直很难搞啊,尤其是像我这种数学很挫的学渣,压根不懂什么凸包,什么上凸下凸的,哎...说多了都是泪,跟wdd讨论了下,得出一些结论.本文很大部分参考了大神Accept的文章,不过此神貌似早已绝迹江湖,这篇文章写得好,也写得很差,前半部分叙述得很好,可是关键,关键部分说得很乱,有些许错误,很多大神都进行了评论指出,但是大神Accept貌似没有修改的意思,故重新总结下,以便自己以后查阅和复习啊. 下面看一个例题Print Article.

HDU - 5009 Paint Pearls(dp+双向链表优化)

Problem Description Lee has a string of n pearls. In the beginning, all the pearls have no color. He plans to color the pearls to make it more fascinating. He drew his ideal pattern of the string on a paper and asks for your help. In each operation,

【BZOJ-1010】玩具装箱toy DP + 斜率优化

1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8432  Solved: 3338[Submit][Status][Discuss] Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P

POJ 1185 炮兵阵地 状压DP+离散化优化

一开始能想到的状态就只有位压两行和当前行的行号,这样无论是空间和时间都是无法接受的. 但是因为炮兵的攻击范围比较大,而且又有地形限制,每一行的状态其实不多了,打表看了一下不超过80种,离散化一下就可以随意DP了. 据说题目也可以抽象成二分图最大匹配来搞?感觉复杂度有点高 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #i

DP常用优化

DP常用优化 一.前缀和优化 当遇到类似:\(f[i] = \sum_{j = k}^{i} g[j]\)的转移时,可以通过预处理出\(g[i]\)的前缀和\(s[i]\),将\(O(n)\)的求和转换为\(O(1)?\)的操作. [HAOI2009]逆序对数列 [HAOI2008]木棍分割 二分答案+dp P4099 [HEOI2013]SAO 树形dp 二.决策单调性--单调队列优化 接下来几种优化方法主要是对1d/1d dp的优化,其中xd/yd dp指的是状态数有\(n^x\)种,每个状

BZOJ 1096: [ZJOI2007]仓库建设(DP+斜率优化)

[ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用.突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏.由于地形的不同,在不同工厂建立仓库的费用可能是不同的.第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci.对于没有建立仓库的工厂,其