2015 CCPC-C-The Battle of Chibi (UESTC 1217)(动态规划+树状数组)

赛后当天学长就说了树状数组,结果在一个星期后赖床时才有了一点点思路……

因为无法提交,不确定是否正确。。嗯。。有错希望指出,谢谢。。。

嗯。。已经A了。。提交地址http://acm.uestc.edu.cn/#/problem/show/1217

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

/**
题意:T代表测试组数 (T<=100)
     每组两个数N, M(1<=N<=1000,1<=M<=N)
     给N个数ai(1<=ai<=10^9)
     求该数列的m长递增子序列
方法:容易想到dp[i][k]表示到第i个数,长度为k的子序列,O(N^3)可解
     通过树状数组可以优化到O(N^2lgN)
*/

struct node{
    int data;
    int pos;
    bool operator < (const node a) const
    {
        if (data == a.data)
            return pos < a.pos;
        return data < a.data;
    }
} a[1005];

int c[1005][1005];      // c[k][i] 结尾数字为i,长度为k的子序列数量
int b[1005];
int N, M;

const int MOD = 1000000007;

int lowbit(int x)
{
    return x & (-x);
}

int sum(int x, int n)
{
    int ans = 0;
    while (n > 0) {
        ans = (ans + c[x][n]) % MOD;
        n -= lowbit(n);
    }
    return ans;
}

void plu(int x, int pos, int num)
{
    while (pos <= N) {
        c[x][pos] = (c[x][pos] + num) % MOD;
        pos += lowbit(pos);
    }
}


int main()
{
    int t, cas = 0;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d%d", &N, &M);
        for (int i = 1; i <= N; ++i)
        {
            scanf("%d", &a[i].data);
            a[i].pos = i;
        }

        // 离散化
        sort(a + 1, a + N + 1);
        int cnt = 1;
        b[a[1].pos] = cnt;
        for (int i = 2; i <= N; ++i)
        {
            if (a[i].data > a[i - 1].data) cnt++;
            b[a[i].pos] = cnt;
        }

        //for (int i = 1; i <= N; ++i) cout << b[i] << endl;

        memset(c, 0, sizeof c);

        for (int i = 1; i <= N; ++i)
        {
            plu(1, b[i], 1);        // 以每个数结尾的长度为1的数都是1
            for (int k = 2; k <= M; ++k)
            {
                int temp = sum(k - 1, b[i] - 1); // 所有比b[i]小的数长度为k-1的和就是以b[i]为结尾的长度为k的了。。
                plu(k, b[i], temp);
            }
        }

        int ans = sum(M, N);
        printf("Case #%d: %d
", ++cas, ans);
    }
    return 0;
}

/**
Input:
5
3 2
1 2 3
3 2
3 2 1
3 1
1 2 3
3 2
1 1 2
7 3
1 1 2 2 1 1 4

Output:
3
0
3
2
4
*/

  

原文地址:https://www.cnblogs.com/wenruo/p/4906333.html