Description

给定一个长度为n的序列(n <= 100) ,给定m(m <= n),求该序列中有多少值不相同的长度为m的严格上升子序列。

Input

先输入一个T,表明下面会有几组数据。
每组数据先输入一个n,m,表明数组大小和上升子序列长度。
下面一行有n个数代表该数组,且 1<=a[i]<=n;

Output

输出为一行,只需输出上述要求的个数(结果对1000000009取余)。

Sample Input

4
2 2
1 2
4 3
1 2 4 4
5 4
1 2 3 5 4
5 1
1 1 1 2 2

Sample Output

1
1
2
2
思路:
还是第三届山科校赛的题目
这个题开两个二维dp数组,第二个是一个延时的dp
也就是没有更新当前状态的dp
再开一个一维数组记一下当前位置数字上次出现的位置
如果上次出现过的话就减掉上一次的dp值去重
dp[i][j]表示以值i为结尾长度为j的最长上升子序列的不同值的数量
具体看代码吧。。
/* ***********************************************
Author        :devil
Created Time  :2016/4/26 22:18:57
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
typedef long long LL;
const int N=110;
const int mod=1e9+9;
LL dp[N][N],dp2[N][N];
int a[N],b[N];
int main()
{
    //freopen("in.txt","r",stdin);
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        memset(dp,0,sizeof(dp));
        memset(dp2,0,sizeof(dp2));
        memset(b,-1,sizeof(b));
        b[a[1]]=dp[a[1]][1]=1;
        for(int i=2;i<=n;i++)
        {
            dp[a[i]][1]=1;
            int mi=min(i,m);
            for(int k=2;k<=mi;k++)
            {
                for(int j=1;j<a[i];j++)
                {
                    dp[a[i]][k]+=dp[j][k-1];
                    if(dp[a[i]][k]>=mod) dp[a[i]][k]-=mod;
                }
                if(b[a[i]]!=-1)
                {
                    dp[a[i]][k]-=dp2[a[i]][k];
                    if(dp[a[i]][k]<0) dp[a[i]][k]+=mod;
                }
                dp2[a[i]][k]=dp[a[i]][k];
            }
            b[a[i]]=i;
        }
        LL ans=0;
        for(int i=1;i<=n;i++)
            ans=(ans+dp[i][m])%mod;
        printf("%lld\n",ans);
    }
    return 0;
}