hdu5542 CCPC中国赛 dp + 树状数组

来源:互联网 发布:人类为何不优化人种 编辑:程序博客网 时间:2024/05/24 06:49

题意是给你n个数让你求选出m个数且单调递增的个数;

首先给出的数值特别大  而数的个数才1000  所以先离散处理下  ;

具体思路:   dp+树状数组;

我是建了m棵树   用来记录没j个的情况       dp【i】【j】表示以j结尾的数 里面递增数为i个 求这些书里面包含num【j】的情况  这样跑i   建树  

初始化dp【1】【j】 = 1;

 for(i = 2; i <= m; i++)        {            memset(sum, 0, sizeof(sum));            for(j = 1; j <= n; j++)            {                dp[i][j] = (dp[i][j] + find(num[j].value - 1)) % mod;                    update(num[j].value, dp[i - 1][j]);            }                    }
至于建树和求和按照正常来就行

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;const int Max = 1010;const int mod = 1e9 + 7;struct node{    int value;    int ii;}num[Max];__int64 sum[Max];__int64 dp[Max][Max];int cmp(node a, node b){    return a.value < b.value;}int cmp1(node a, node b){    return a.ii < b.ii;}int update(int a, __int64 c){        for(int i = a; i <= 1000; i += (i&(-i)))    sum[i] = (sum[i] + c) % mod;    return 0;}__int64 find(int a){    __int64 s = 0;    for(int i = a; i >= 1; i -= i&(-i))    s = (s + sum[i]) % mod;    return s;}int main(){    int T, i, j, n, m, d = 1;        scanf("%d", &T);    while(T--)    {        scanf("%d%d", &n, &m);        for(i = 1; i <= n ; i++)        {            scanf("%d", &num[i].value);            num[i].ii = i;        }        sort(num + 1, num + 1 + n, cmp);        int k = -1;        int x = 0;        for(i = 1; i <= n; i++)        {            if(num[i].value != k)            {                k = num[i].value;                num[i].value = ++x;            }            else            {                num[i].value = x;            }        }        sort(num + 1, num + 1 + n, cmp1);        memset(dp, 0, sizeof(dp));        for(i = 1; i <= n; i++)        dp[1][i] = 1;                for(i = 2; i <= m; i++)        {            memset(sum, 0, sizeof(sum));            for(j = i-1; j <= n; j++)            {                dp[i][j] = (dp[i][j] + find(num[j].value - 1)) % mod;                    update(num[j].value, dp[i - 1][j]);            }                    }        __int64 ans = 0;        for(i = 1; i<= n; i++)        ans = (ans + dp[m][i]) % mod;        printf("Case #%d: ", d++);        printf("%I64d\n", ans);    }        return 0;}

0 0