hdu4991 - Ordered Subsequence (树状数组优化)

这个题是bestcoder #8 的第三个。 比赛时用O(n*n)的dp做超时。 赛后看了hdu官网的题解, 用树状数组优化O(n*n*m)的dp。弱渣开眼了。。。



首先数字有1万个,先离散化一下,把所有数字对应到1到n之间。这样对结果不影响。

dp[i][j]代表以第i个数字结尾上升子序列长度为j的种数。

if(a[i]>a[k] && i>k) dp[i][j]=sum{dp[k][j-1]} 


在练习赛的时候又碰到了,竟然一点印象也没有。所以重新做了一遍,之前写的代码也太乱了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn=11000;
const int MOD=123456789;
int bit[110][maxn], arr[maxn], tmp[maxn];
int lowbit(int x)
{
    return x&-x;
}

int Sum(int x, int i)
{
    int res=0;
    for(; i>0; res=(res+bit[x][i])%MOD, i-=lowbit(i));
    return res%MOD;
}
void Add(int x, int i, int v, int n)
{
    for(; i<=n; bit[x][i]=(bit[x][i]+v)%MOD, i+=lowbit(i));
}

int main()
{
//    freopen("in.txt", "r", stdin);
    int n, len;
    while(~scanf("%d%d", &n, &len))
    {
        for(int i=0; i<n; i++)
        {
            scanf("%d", arr+i);
            tmp[i]=arr[i];
        }
        sort(tmp, tmp+n);
        int cnt=unique(tmp, tmp+n)-tmp;
        for(int i=0; i<n; i++)
            arr[i]=lower_bound(tmp, tmp+cnt, arr[i])-tmp+1;
        memset(bit, 0, sizeof(bit));
        Add(1, arr[0], 1, cnt);
        for(int j=1; j<n; j++)
        {
            for(int i=2; i<=len; i++)
            {
                int t=Sum(i-1, arr[j]-1);
                Add(i, arr[j], t, cnt);
            }
            Add(1, arr[j], 1, cnt);
        }
        printf("%d\n", Sum(len, cnt));
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值