码迷,mamicode.com
首页 > 编程语言 > 详细

UVA12983 The Battle of Chibi 树状数组+DP

时间:2018-10-20 21:09:17      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:The   tle   register   mem   query   color   吐槽   ++   mes   

先容蒟蒻吐槽一波:模数看错调了一两小时。。。

题意:

要你在一个长度为n的序列中找到长度为m的严格上升子序列的个数,然后答案对1e9+7取模。

举个例子:

5 3

1 3 4 2 5

那么符合条件的序列就有: 1 3 4 ,1 2 5, 1 3 5 ,1 4 5, 3 4 5, 答案就是5。

既然和上升子序列有关,那么就是DP了。

注意我这里设的i,j有点不一样,表示的是

前j个数,以a[j]结尾的,严格上升子序列长度为i的方案数。(反过来也OK,只不过待会BIT就得开两维)

容易得到状态转移方程:f[i][j]=sigma (f[i-1][k]), 0<=k<j 且 a[k]<a[j]。

那么的话n3的暴力是很容易打的。

但是如果只是n3题目就没多大意义了。

 

我们考虑优化:

显然对于一个j我们只关心他前面的满足 a[k]<a[j] 的所有的方案数的和。

那么这就可以直接建立一个权值树状数组,(注意到ai<=1e9 离散化即可)

对于每一个数先查询之前的比他小的,统计一下答案。

再把自己的值插入自己的对应的位置就可以了。

可以发现由于我们的 i  是在外层循环,即已经限制了长度, 所以内部更新时i-1不变。

所以只要直接建一维的BIT就好了,不要考虑把长度也记下来,只是每次i++后,清空BIT。

#include <bits/stdc++.h>
using namespace std;
inline int gi () {
    int x=0,w=0; char ch=0;
    while (!(ch>=0 && ch<=9)) {if (ch==-) w=1; ch=getchar ();}
    while (ch>=0 && ch<=9) x= (x<<3)+(x<<1)+(ch^48), ch=getchar ();
    return w?-x:x;
}

#define LL long long
#define INF 0x3f3f3f3f;
#define RGI register int
#define lowbit(x) x&-x

const int N=1010;
const int Mod=1e9+7;

LL Ans,BIT[N],f[N][N];
int T,n,m,tot,a[N],b[N];

inline void New_Case () {
    memset (f, 0 ,sizeof (f));
    f[0][0]=1, Ans=0, a[0]=1;  
}

inline void Modify (int x, int val) {
    for (;x<=n;x+=lowbit(x)) BIT[x]=(BIT[x]+val%Mod)%Mod; 
}

inline LL Query (int x) {
    LL sum=0;
    for (;x;x-=lowbit(x)) sum=(sum+BIT[x])%Mod;
    return sum;
}

int main ()
{
    T=gi ();
    for (RGI id=1;id<=T;++id) {
        RGI i,j;
        New_Case ();
        n=gi (), m=gi ();
        for (i=1;i<=n;++i) a[i]=b[i]=gi ();
        sort (b+1, b+n+1);
        for (i=1;i<=n;++i) a[i]=lower_bound (b+1, b+n+1, a[i])-b+1;
        for (i=1;i<=m;++i) {
            memset (BIT, 0, sizeof (BIT));
            Modify (a[0], f[i-1][0]);
            for (j=1;j<=n;++j) {
                f[i][j]=Query (a[j]-1);
                Modify (a[j], f[i-1][j]%Mod);
            }
        }
        for (i=1;i<=n;++i) Ans= (Ans+f[m][i])%Mod;
        printf ("Case #%d: %lld\n", id, Ans);
    }
    return 0;
}

 

UVA12983 The Battle of Chibi 树状数组+DP

标签:The   tle   register   mem   query   color   吐槽   ++   mes   

原文地址:https://www.cnblogs.com/Bhllx/p/9822815.html

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