Ordered Subsequence

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 464    Accepted Submission(s): 216

Problem Description
A numeric sequence of ai is ordered if a1<a2<……<aN. Let the subsequence of the given numeric sequence (a1, a2,……, aN) be any sequence (ai1, ai2,……, aiK), where 1<=i1<i2 <……<iK<=N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, eg. (1, 7), (3, 4, 8) and many others.

Your program, when given the numeric sequence, must find the number of its ordered subsequence with exact m numbers.

 
Input
Multi
test cases. Each case contain two lines. The first line contains two
integers n and m, n is the length of the sequence and m represent the
size of the subsequence you need to find. The second line contains the
elements of sequence - n integers in the range from 0 to 987654321 each.
Process to the end of file.
[Technical Specification]
1<=n<=10000
1<=m<=100
 
Output
For each case, output answer % 123456789.
 
Sample Input
3 2
1 1 2
7 3
1 7 3 5 9 4 8
 
Sample Output
2
12
 
题意:问在 长度为n的串中有多少个长度为 m 的上升子序列.
题解:dp[i][j]代表以第 i 个元素结尾,长度为 j 的子序列 的个数。那么 dp[i][j] = sum(dp[k][j-1]) (1<=k<j).
但是这样的话我们直接枚举是 O(n*n*m)这样的时间复杂度是接受不了的。所以求和的那一层用树状数组优化成 O(n*log(n)*m)
/**
状态转移方程:
dp[i][j] = sum(dp[k][j-1]) (1<=k<i&&a[k]<a[i])
*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL mod = ;
const int N = ;
const int M = ;
int cnt,n,m;
LL dp[N][M]; ///dp[i][j]代表第 i 个元素结尾,长度为 j 的递增子序列个数.
LL c[N],b[N],a[N]; LL lowbit(int i){
return i&(-i);
}
void update(int idx,int x,LL v){
for(int i=idx;i<=cnt;i+=lowbit(i)){
dp[i][x]=(dp[i][x]+v)%mod;
}
}
LL getsum(int idx,int x){
LL sum = ;
for(int i=idx;i>;i-=lowbit(i)){
sum=(sum+dp[i][x])%mod;
}
return sum;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=;i<=n;i++){
scanf("%lld",&a[i]);
b[i] = a[i];
}
cnt = ;
for(int i=;i<=n;i++){ ///离散化 a 数组对应树状数组的 1 - cnt
if(b[i]!=b[i-]){
b[++cnt] = b[i];
}
}
sort(b+,b+cnt+);
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++){
int idx = lower_bound(b+,b++cnt,a[i])-b;
for(int j=;j<=m;j++){
LL v;
if(j == ) v = ;
else v = getsum(idx-,j-);
update(idx,j,v);
}
}
LL ans = getsum(cnt,m);
printf("%lld\n",ans);
}
return ;
}
    #include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
const int mod=;
int n,m;
int a[];
int b[],cnt; inline void Add(int &a,int b){
a=(a+b)%mod;
}
inline int lowbit(int x){
return x&(-x);
}
int sum[][];
inline void add(int id,int x,int v){
while(x<=cnt){
Add(sum[id][x],v);
x+=lowbit(x);
}
}
inline int query(int id,int x){
int ans=;
while(x){
Add(ans,sum[id][x]);
x-=lowbit(x);
}
return ans;
} int main(){
while(~scanf("%d%d",&n,&m)){
cnt=;
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
b[++cnt]=a[i];
}
sort(b+,b+cnt+);
cnt=(int)(unique(b+,b++cnt)-(b+));
for(int i=;i<=n;i++)a[i]=(int)(lower_bound(b+,b++cnt,a[i])-b); memset(sum,,sizeof sum); int ans=;
for(int i=;i<=n;i++){
for(int j=;j<m;j++){
if(a[i]>){
int sum=query(j,a[i]-);
add(j+,a[i],sum);
}
}
add(,a[i],);
}
ans=query(m,cnt);
printf("%d\n",ans);
}
return ;
}

hdu 4991(树状数组+DP)的更多相关文章

  1. hdu 2227(树状数组+dp)

    Find the nondecreasing subsequences Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/3 ...

  2. hdu 4638 树状数组 区间内连续区间的个数(尽可能长)

    Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  3. hdu 4777 树状数组+合数分解

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  4. hdu 4622 Reincarnation trie树+树状数组/dp

    题意:给你一个字符串和m个询问,问你l,r这个区间内出现过多少字串. 连接:http://acm.hdu.edu.cn/showproblem.php?pid=4622 网上也有用后缀数组搞得. 思路 ...

  5. 2018 CCPC网络赛 1010 hdu 6447 ( 树状数组优化dp)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6447 思路:很容易推得dp转移公式:dp[i][j] = max(dp[i][j-1],dp[i-1][j ...

  6. 【树状数组+dp】HDU 5542 The Battle of Chibi

    http://acm.hdu.edu.cn/showproblem.php?pid=5542 [题意] 给定长为n的序列,问有多少个长为m的严格上升子序列? [思路] dp[i][j]表示以a[i]结 ...

  7. HDU 6348 序列计数 (树状数组 + DP)

    序列计数 Time Limit: 4500/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Subm ...

  8. hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

    Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...

  9. HDU 6447 YJJ’s Salesman (树状数组 + DP + 离散)

    题意: 二维平面上N个点,从(0,0)出发到(1e9,1e9),每次只能往右,上,右上三个方向移动, 该N个点只有从它的左下方格点可达,此时可获得收益.求该过程最大收益. 分析:我们很容易就可以想到用 ...

随机推荐

  1. CDOJ:1636-梦后楼台高锁,酒醒帘幕低垂(Kruskal+暴力)

    梦后楼台高锁,酒醒帘幕低垂 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...

  2. 动态规划:HDU2844-Coins(多重背包的二进制优化)

    Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  3. BFS:HDU2054-A==B?(字符串的比较)

    A == B ? Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  4. 9、python中的控制流

    学习完python的基础与数据后,我们就可以编写一些简单的命令了.但这时我们发现,目前位置写出来的程序都是自上而下顺序地执行的.要想程序改变这种自上而下的流程多一点变化,我们就要学习三种程序中的语句. ...

  5. open()函数之文件操作

    #open() 文件操作 #打开文件的模式有: r,只读模式[默认] w,只写模式[不可读:不存在则创建:存在则清空内容:] x,只写模式[不可读:不存在则创建,存在则报错] a,追加模式[可读:不存 ...

  6. SQL中的函数用法

    一.coalesce COALESCE (expression_1, expression_2, ...,expression_n)依次参考各参数表达式,遇到非null值即停止并返回该值.如果所有的表 ...

  7. 1568: [JSOI2008]Blue Mary开公司(超哥线段树)

    1568: [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1198  Solved: 418 Descr ...

  8. Maven web项目的项目如何创建

    1.eclipse--创建maven项目--选择打包方式为war 2.此时项目还缺少一些东西,比如web-inf,web.xml配置文件之类的 3.项目右键-properties-project fa ...

  9. day20 Django Models 操作,多表,多对多

    1 Django models 获取数据的三种方式: 实践: viwes def business(request): v1 = models.Business.objects.all() v2 = ...

  10. day 16 JS DOM 继续

    为什么有jquey了还学DOM  ? 因为JQuey 是大而全,可能有10k 但是我们用到的只有1k  网站小没事,网站大流量就是问题 所以大网站都是自己用DOM 实现一个类似于JQuey 的适合自己 ...