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<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int mod=1e9+7;
int n,m;
int a[1005];
int b[1005];
int dp[1005][1005];
int sum(int x,int y)
{
    int ans=0;
    while(x)
    {
        ans=(ans+dp[x][y])%mod;
        x-=x&-x;
    }
    return ans;
}
void add(int x,int y,int val)
{
    while(x<=n)
    {
        dp[x][y]=(dp[x][y]+val)%mod;
        x+=x&-x;
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    for(int ca=1;ca<=T;ca++)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+1+n);
        for(int i=1;i<=n;i++)
            a[i]=lower_bound(b+1,b+1+n,a[i])-b;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            int t=min(i,m);
            for(int j=1;j<=t;j++)
            {
                if (j==1) add(a[i],1,1);
                else
                {
                    int t=sum(a[i]-1,j-1);
                    add(a[i],j,t);
                }
            }
        }
        printf("Case #%d: %d\n",ca,sum(n,m));
    }
    return 0;
}

  

时间: 2024-12-07 19:46:15

HDU 5542 The Battle of Chibi dp+树状数组的相关文章

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.

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)的,显然

HDU 2227 Find the nondecreasing subsequences (DP+树状数组+离散化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227 Find the nondecreasing subsequences                                  Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)                                             

树形DP+树状数组 HDU 5877 Weak Pair

1 //树形DP+树状数组 HDU 5877 Weak Pair 2 // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 3 // 这道题要离散化 4 5 #include <bits/stdc++.h> 6 using namespace std; 7 #define LL long long 8 typedef pair<int,int> pii; 9 const double inf = 12345678901234

hdu 3584 二进制0,1反转 三维树状数组 及三维树状数组模板

先贴自己类比二维树状数组写的三维树状数组模板: 开始的时候循环体内j=y,k=z,没写,以为自己思路错了,,,hehe..... 更高维的树状数组以此类比 const int MAXN = 100+10; int c[MAXN][MAXN][MAXN];int X,Y,Z; int N; inline int lowbit(int x){return x&(-x);} void update(int x, int y, int z, int v) { int i=x,j=y,k=z; while

poj 3616 Milking Time dp+树状数组

题意: 给一堆区间,每个区间有开始时间s,结束时间e,和收益w,现在要找一些区间使收益和最大,且区间之间的间隔最小为r. 分析: 这道题用dp做是简单题,用dp+树状数组做是中等题.dp问题的关键是对状态的定义.有两种方法,一:dp[k]表示按开始时间排序到第k个区间能取得的最大收益.二:dp[t]表示在时间t时能获得的最大收益.定义好状态方程就好写了这不再赘述.有趣的是这个时间复杂度.设一共有M个区间,所有区间的最大时间为L,第一种是M^2的,第二种是M*(logL+logM)的,这题M才10

HDU 4417 类似求逆序数的树状数组

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2250    Accepted Submission(s): 1092 Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability

奶牛抗议 DP 树状数组

奶牛抗议 DP 树状数组 USACO的题太猛了 容易想到\(DP\),设\(f[i]\)表示为在第\(i\)位时方案数,转移方程: \[ f[i]=\sum f[j]\;(j< i,sum[i]-sum[j]\ge0) \] \(O(n^2)\)过不了,考虑优化 移项得: \[ f[i]=\sum f[j]\;(j< i,sum[i]\ge sum[j]) \] 这时候我们发现相当于求在\(i\)前面并且前缀和小于\(sum[i]\)的所有和,这就可以用一个树状数组优化了,在树状数组维护下标为

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

http://acm.hdu.edu.cn/showproblem.php?pid=5542 [题意] 给定长为n的序列,问有多少个长为m的严格上升子序列? [思路] dp[i][j]表示以a[i]结尾的长度为j的严格上升子序列有多少个 dp[i][j]=sum{dp[k][j-1]},k小于i且a[k]<a[i] 区间dp,复杂度为O(n^3) 会超时,第三层循环求和用树状数组加速 时间复杂度为O(n^2logn) 离散化的时候排序后不去重(否则WA) [Accepted] #include<