题解:UESTC1217 The Battle of Chibi

题意:对于一个N个数的序列求长度为M的上升子序列总数(结果取%)

1<=N<=1000;1<=M<=N;1<=ai<=109.共1~100组数据,4000MS

解题思路:

考虑使用DP,先写出最朴素形式,DP[i][j][k]表示已判断到第i个数,序列长度为j,前一个数大小为k(已离散化)时方案数。复杂度为O(N*M*N),直接上显然会T

优化方法较为明显,维护n个树状数组S[i],S[j][k]表示到当前为止,最大数小于k且长度为j的序列总数,则每次对S[j](j从min(i,m)到1)进行操作:add(a[i]+1,tmp),其中tmp=ask(j-1,a[i]),则每次转移结束,S[j][k]保存从1到i的所有可能状态,复杂度O(NMlogN)

注意点:S数组转移时循环变量应采用倒序

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int mo=1000000007;
const int maxn=1001;
int t,n,m,now,maxs,tmp,ans,gd,wz;
int s[2000][maxn+5];
int jl[2000],ys[2000];
int c[2000];

int lowbit(int x){return (x&(-x));}

void add(int u,int x,int value){
    for (int i=x;i<=maxs+1;i+=lowbit(i)){
        s[u][i]=(s[u][i]+value)%mo;
    }
}

int ask(int u,int x){
    {
        int sum=0;
        for (int i=x;i;i-=lowbit(i)) sum=(sum+s[u][i])%mo;
        return sum;
    }
}

bool cmd(int a,int b){
    return (jl[a]<jl[b]);
}

int main(){
    freopen("1.in","r",stdin);
    freopen("1.out1","w",stdout);
    scanf("%d",&t);
    for (int q=1;q<=t;++q){
        scanf("%d%d",&n,&m);maxs=0;
        for (int i=1;i<=n;++i) {scanf("%d",&jl[i]);ys[i]=jl[i];}
        for (int i=1;i<=n;++i) c[i]=i;
                sort(c+1,c+1+n,cmd);
           jl[c[1]]=1;wz=0;
           for (int i=2;i<=n;++i){
               if (ys[c[i]]==ys[c[i-1]]) ++wz;
               jl[c[i]]=i-wz;
        }
        maxs=n-wz;
        memset(s,0,sizeof(s));
        add(1,jl[1]+1,1);add(0,1,1);
        for (int i=2;i<=n;++i){
            for (int j=min(i,m);j>=1;--j) if (j>i) break; else {
              tmp=(ask(j-1,jl[i])) % mo;
              if (tmp!=0) add(j,jl[i]+1,tmp);
            }
        }
        //cout<<s[0][2]<<endl;
        int ans=ask(m,maxs+1) % mo;
        printf("Case #%d: %d\n",q,ans);
    }
    return 0;
}
时间: 2024-10-22 13:17:47

题解:UESTC1217 The Battle of Chibi的相关文章

2015南阳CCPC C - The Battle of Chibi DP

C - The Battle of Chibi Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description 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 to have a spy in Cao

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

HDU - 5542 The Battle of Chibi(LIS+树状数组优化)

The Battle of Chibi 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 to have a spy in Cao Cao's army. But all generals and soldiers of Cao Cao were loya

The Battle of Chibi

The Battle of Chibi 给出一段长度为n的序列\(\{a_i\}\),求其中长度为m的严格上升子序列个数\(mod\ 10^9+7\),\(n\leq 10^3\). 解 不难想到设\(f[i][j]\)表示以第i个位置结尾,长度为j的LSIS,因此我们有 \[f[i][j]=\sum_{k=1,a_i>a_k}^{i-1}f[k][j-1]\] 边界:\(f[i][1]=1,i=1,2,...,n\),其余为0 答案:\(\sum_{i=1}^nf[i][m]\) 注意到这是\

HDU 5542 - The Battle of Chibi - [离散化+树状数组优化DP]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5542 Problem DescriptionCao 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 to have a spy in Cao Cao's army.

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

HDU5542 The Battle of Chibi(dp)

题意: 给你一个长度为n(1e3)的数列,让你找出长度为m的上升子序列的个数 思路: f[i][j]表示以第i个数为结尾,长度为j的上升子序列的个数,枚举i和j是n^2的,统计的时候用树状数组维护一下 /* *********************************************** Author :devil ************************************************ */ #include <cstdio> #include <

ccpc_南阳 C The Battle of chibi dp + 树状数组

题意:给你一个n个数的序列,要求从中找出含m个数的严格递增子序列,求能找出多少种不同的方案 dp[i][j]表示以第i个数结尾,形成的严格递增子序列长度为j的方案数 那么最终的答案应该就是sigma(dp[i][m]); 显然有:dp[i][j] = sigma(dp[k][j - 1]); 其中 1 <= k < i 且 a[k] < a[i]; 题目要求严格递增,这个限制怎么解决? hdu4719这道题同样是这样处理,即我们只需要从小到大dp就行了. 但是复杂度是O(n^3)的,显然

HDOJ 5542 The Battle of Chibi

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题目大意:在n个数中找长度为m的单调上升子序列有多少种方案 题目思路:DP,离散化,树状数组优化, dp[i][j]代表大小为i的数 长度为j时的方案,状态转移方程dp[i][j]=simiga(dp[1..i-1][j-1]) 如果直接求和的话,复杂度是n^3不行 用树状数组优化求和 复杂度n^2logn n<=1000,a[i]<=1e9,所以离散化搞一下就行 1 #include &l