UVA12983The Battle of Chibi

很容易想到(n^3)的DP:

定义:f[i][j]表示前j个数构成的以j为结尾的数列中,长度为i的严格递增子序列的个数。

for(int i=1;i<=m;i++)
    for(int j=i;j<=n;j++)
        for(int k=0;k<j;k++)
            if(a[k]<a[j])
                f[i][j]=(f[i][j]+f[i-1][k])%mod;
int ans=0;
for(int i=1;i<=n;i++)
    ans=(ans+f[m][i])%mod;

下面我们来想该怎样优化:

首先看到这个数据比较大,应该会想到离散化一下。

a[0].x=-INF,a[0].id=1;
for(int i=1;i<=n;i++)scanf("%d",&a[i].x),a[i].id=i+1;
sort(a,a+n+1,cmp);
for(int i=0;i<=n;i++)b[i]=a[i].id;

然而由a[k]<a[j]就很容易想到用树状数组来优化。

将f[i]的树值先用树状数组存下,需要的时候直接求和,然后求出在读入

具体代码如下:

f[0][0]=1;
for(int i=1;i<=m;i++){
    memset(c,0,sizeof(c));
    add(b[0],f[i-1][0]);
    for(int j=1;j<=n;j++){
        f[i][j]=ask(b[j]-1);
        add(b[j],f[i-1][j]);
        }
}

再给个完整代码吧:

#include<bits/stdc++.h>
#define INF 0x7fffffff
using namespace std;
struct note{
    int x,id;
}a[1010];
int T,n,m;
long long c[1010],f[1010][1010],ans,mod=1000000007;
int b[1010];
bool cmp(note aa,note bb){return (aa.x==bb.x?aa.id>bb.id:aa.x<bb.x);}

////////////////////////////树状数组的操作
int lowbit(int x){return x&(-x);};
void add(int x,int k){for(int i=x;i<=n+1;i+=lowbit(i))c[i]=(c[i]+k)%mod;}
long long ask(int x){long long sum=0;for(int i=x;i>0;i-=lowbit(i))sum=(sum+c[i])%mod;return sum;}
////////////////////////////

int main(){
    scanf("%d",&T);
    for(int t=1;t<=T;t++){
        scanf("%d%d",&n,&m);
        memset(f,0,sizeof(f));
        ans=0;

        ////////////////////////////离散化操作
        a[0].x=-INF,a[0].id=1;
        for(int i=1;i<=n;i++)scanf("%d",&a[i].x),a[i].id=i+1;
        sort(a,a+n+1,cmp);
        for(int i=0;i<=n;i++)b[i]=a[i].id;
        ////////////////////////////

        f[0][0]=1;
        for(int i=1;i<=m;i++){
            memset(c,0,sizeof(c));
            add(b[0],f[i-1][0]);
            for(int j=1;j<=n;j++){
                f[i][j]=ask(b[j]-1);
                add(b[j],f[i-1][j]);
            }
        }
        for(int i=1;i<=n;i++)ans=(ans+f[m][i])%mod;
        printf("Case #%d: %lld\n",t,ans);
    }
    return 0;
}

结束语:

多组数据需注意,memeset别忘记。

树状数组留意0,否则就要TLE。

全部评论

相关推荐

11-07 13:31
怀化学院 Java
勇敢牛牛不怕难:又疯一个
点赞 评论 收藏
分享
10-15 09:13
已编辑
天津大学 soc前端设计
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务