码迷,mamicode.com
首页 > 其他好文 > 详细

UVA12983 The Battle of Chibi

时间:2019-10-06 00:38:04      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:树状   离散化   sdi   printf   mes   memset   +=   read   暴力   

第一眼能看出来是个dp

O($n^3$) 暴力应该很好想 dp[i][j] = $\sum_{k=1}^i [a[k] < a[i]] *dp[k][j-1]$

发现dp[i][j] 为前面小于它的数长度为j-1的总和, 用树状数组前缀和优化一下搞成$O(n^2log_n)$

先离散化, dp时先枚举位置,再枚举上升序列的长度

树状数组要开二维哦, 打代码的时候发现dp数组可以用树状数组直接代替(小小的空间优化)

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1005;
const int P = 1e9+7;
int read(void) {
    int x = 0;
    char c = getchar();
    while (!isdigit(c)) c = getchar();
    while (isdigit(c)) {
        x = (x << 3) + (x << 1) + c - '0';
        c = getchar();
    }
    return x;
}
int T, n, m;
int a[N];
struct node{
    int pos, val;
    bool operator < (const node &i) const {
        if (val == i.val) return pos < i.pos;
        return val < i.val;
    }
}p[N];
bool cmp(node i,node j) {
    return i.pos < j.pos;
}
long long d[N][N];
inline int low(int x) {
    return x & -x;
}
int sum(int x,int p) {
    long long val = 0;
    for (;x;x -= low(x)) val += d[p][x];
    return val % P;
}
void add(int x,int k,int p) {
    for (;x <= n; x += low(x)) d[p][x] = (d[p][x] + k) % P;
}
int main() {
    T = read();
    int cnt = 0;
    while (T--) {
        cnt++;
        n = read(), m = read();
        for (int i = 1;i <= n; i++) p[i] = (node){i,read()};
        sort(p + 1,p + n + 1);
        int x = 0, k = 0;
        for (int i = 1;i <= n; i++) {
            if (x == p[i].val) 
                p[i].val = k;
            else {
                x = p[i].val;
                p[i].val = i;
                k = i;
            }
        }
        sort(p + 1,p + n + 1, cmp);
        memset(d, 0, sizeof(d));
        long long ans = 0;
        for (int i = 1;i <= n; i++) {
            add(p[i].val, 1, 1);
            for (int j = 2;j <= m; j++) {
                int k = sum(p[i].val-1, j-1);
                add(p[i].val, k, j);
                if (j == m) ans = (ans + k) % P;
            }
        }
        if (m == 1) ans += n;
        printf ("Case #%d: %lld\n", cnt, ans % P);
    }
    return 0;
}
                

UVA12983 The Battle of Chibi

标签:树状   离散化   sdi   printf   mes   memset   +=   read   暴力   

原文地址:https://www.cnblogs.com/Hs-black/p/11626109.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!