【树状数组+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<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>

using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=1e3+3;
ll a[maxn];
ll b[maxn];
ll dp[maxn][maxn];
int cnt;
int n,m;
int lowbit(int x)
{
    return x&(-x);
}

ll add(int x,int y,ll d)
{
    while(x<=n)
    {
        dp[x][y]=(dp[x][y]+d)%mod;
        x+=lowbit(x);
    }
}

ll sum(int x,int y)
{
    ll res=0ll;
    while(x)
    {
        res=(res+dp[x][y])%mod;
        x-=lowbit(x);
    }
    return res;
}
int main()
{
    int T;
    scanf("%d",&T);
    int cas=0;
    while(T--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
        }
        memcpy(b,a,sizeof(b));
        sort(a+1,a+n+1);
        //cnt=unique(a+1,a+n+1)-a-1;
        for(int i=1;i<=n;i++)
        {
            int pos=lower_bound(a+1,a+n+1,b[i])-a;
            for(int j=1;j<=min(i+1,m);j++)
            {
                ll tmp;
                if(j==1) tmp=1ll;
                else tmp=sum(pos-1,j-1);
                add(pos,j,tmp);
            }
        }
        ll ans=sum(n,m);
        printf("Case #%d: %d\n",++cas,(int)ans);
    }
    return 0;
}

【疑问】

为啥不可以去重?

时间: 2024-10-25 23:49:12

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

hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 481    Accepted Submission(s): 245 Problem Description You were driving along a highway when you got caught by the road p

hdu4455之树状数组+DP

Substrings Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1571    Accepted Submission(s): 459 Problem Description XXX has an array of length n. XXX wants to know that, for a given w, what is

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

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(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

hdu 3450(树状数组+dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3450 Counting Sequences Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/65536 K (Java/Others) Total Submission(s): 1815    Accepted Submission(s): 618 Problem Description For a set of seque

hdu 2227 树状数组+dp

题意是求一个数列的不递减的子序列的个数: 很显然,如果只用dp来做的话时间是O(n*n) 因为dp[i]为前i个数可能的方案,则状态转移方程为dp[i]=sum(dp[j],j<i&&num[j]<=num[i])+1 对小数据坑定能过 但大数据就超时了,这里用到了树状数组来优化: 先对num按数来进行排序,(这道题因为数据较大  用到了离散化) 因为更新是是按原序更新的,及i之前的num[j]一定比num[i]小,维护了不递减的原则,更新是从mark[i](表示原序列i在排序

hdu 2227Find the nondecreasing subsequences(树状数组+dp+离散化)

题目链接:点击打开链接 题意描述:给定一个序列,找出其中递增子序列的数量? 解题思路: 1.dp[i]:表示以元素i结尾的子序列的数量,则d[j]=sum(d[i])+1;其中(j>=i且j的下标大于i) 2.此刻我们可以联想到树状数组,按数组下标从小到大的顺序插入元素,那么d[j]就等于sum(j)+1; 3.由于数据范围比较大,我们采用离散化处理即可 代码: #include <cstdio> #include <algorithm> #include <cstri

HDU 6447 YJJ’s Salesman (树状数组 + DP + 离散)

题意: 二维平面上N个点,从(0,0)出发到(1e9,1e9),每次只能往右,上,右上三个方向移动, 该N个点只有从它的左下方格点可达,此时可获得收益.求该过程最大收益. 分析:我们很容易就可以想到用DP,假设这个位置是相对上一个位置的方向而来,但是复杂度达到N^2 ,这样是不行的: 我们可以利用坐标的信息,将所有的点离散化后,以x优先按小到大排序,按y按大到小排序,这时维护一个DP(i) ,表示第I列的最值. j=0→i?1j=0→i?1                           d