【树状数组】 HDU 4991 Ordered Subsequence
DP+树状数组
dp [i] [j] i 表示第i个数 j表示第j大的数 1<= j <=m
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <sstream>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <set>
#include <map>
#define cler(arr, val) memset(arr, val, sizeof(arr))
#define IN freopen ("in.txt" , "r" , stdin);
#define OUT freopen ("out.txt" , "w" , stdout);
typedef long long LL;
const int MAXN = 10011;//点数的最大值
const int MAXM = 20006;//边数的最大值
const int INF = 11521204;
const int mod=123456789;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int a[MAXN],b[MAXN];
void add(int &a,int b)
{
a+=b;
if(a>=mod) a-=mod;
}
struct node
{
int n,sum[MAXN];
void init(int x)
{
n=x;
cler(sum,0);
}
int lowbit(int x)
{
return x&(-x);
}
int query(int pos)
{
int res=0;
while(pos>0)
{
add(res,sum[pos]);
pos-=lowbit(pos);
}
return res;
}
void update(int pos,int x)
{
while(pos<=n)
{
add(sum[pos],x);
pos+=lowbit(pos);
}
}
}bit[110];
int dp[MAXN][110];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(a+1,a+n+1);
int cnt=unique(a+1,a+n+1)-a;
for(int i=0;i<=m;i++) bit[i].init(n);
cler(dp,0);
bit[0].update(1,1);
dp[0][0]=1;
int ans=0;
for(int i=1; i<=n; i++)
{
int x;
x=lower_bound(a+1,a+cnt,b[i])-a;
for(int j=1;j<=m;j++)
{
add(dp[i][j],bit[j-1].query(x));
bit[j].update(x+1,dp[i][j]);
}
add(ans,dp[i][m]);
}
printf("%d\n",ans);
}
return 0;
}

浙公网安备 33010602011771号