HDU5542(dp+树状数组)

来源:互联网 发布:电气制图cad软件 编辑:程序博客网 时间:2024/05/21 07:03

题目大意:南阳CCPC的C题,找n个数字的严格上升的长度为m的子串。

思路:n^3的dp,用树状数组优化到n^2*logn。

#include <cstdio>#include <algorithm>#include <cstring>#include <iostream>#include <string>#include <cmath>using namespace std;const long long mod = 1000000007;const int maxn = 1111;long long c[maxn][maxn], dp[maxn][maxn];int n, m;long long a[maxn], pos[maxn];int lowbit(int x){    return x & (-x);}void modify(int pos, int k, long long val){    for(int i=pos; i<=n; i+=lowbit(i))    {        c[i][k] += val;        c[i][k] %= mod;    }}long long query(int pos, int k){    long long res = 0;    for(int i=pos; i>0; i-=lowbit(i))    {        res += c[i][k];        res %= mod;    }    return res;}int main(){    int T, kase = 0;    scanf("%d", &T);    while(T--)    {        scanf("%d%d", &n, &m);        for(int i=1; i<=n; i++)        {            scanf("%lld", &a[i]);            pos[i] = a[i];        }        sort(pos+1, pos+1+n);        memset(c, 0, sizeof c);        modify(1, 0, 1);        memset(dp, 0, sizeof dp);        for(int i=1; i<=n; i++)        {            int p = lower_bound(pos+1, pos+1+n, a[i]) - pos;            for(int j=1; j<=i; j++)            {                dp[i][j] = query(p, j-1);                dp[i][j] %= mod;                modify(p+1, j, dp[i][j]);                if(!dp[i][j])                    break;            }        }        long long ans = 0;        for(int i=m; i<=n; i++)        {            ans += dp[i][m];            ans %= mod;        }        printf("Case #%d: %lld\n", ++kase, ans);    }    return 0;}

0 0
原创粉丝点击