加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

UVA12983 The Battle of Chibi

发布时间:2020-12-14 04:40:03 所属栏目:大数据 来源:网络整理
导读:第一眼能看出来是个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

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,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: %lldn",cnt,ans % P);
    }
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读