dp[i][j]表示以a[i]结尾的长度为j的上升子序列个数。

方程:dp[i][j]=sum(dp[k][j-1]),a[k]<a[i],1<=k<i。

求解目标:sum(dp[k][m]),1<=k<=n。

三层循环枚举的话要超时,观察式子,相当于是统计前缀和,这启示我们可以用到树状数组来优化,复杂度mnlogn。

值域较大,要使用离散化。

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 #define mod 123456789
5 typedef long long ll;
6 using namespace std;
7 #define N 10005
8
9 ll a[N],b[N];
10 ll dp[N][105];
11 int n,m,len;
12
13 int lowbit(int x){
14 return x&(-x);
15 }
16
17 void add(int i,int j,ll val){
18 while(i<=len){
19 dp[i][j]=(dp[i][j]+val)%mod;
20 i+=lowbit(i);
21 }
22 }
23
24 ll query(int i,int j){
25 ll res=0;
26 while(i){
27 res=(res+dp[i][j])%mod;
28 i-=lowbit(i);
29 }
30 return res;
31 }
32
33
34
35 int main(){
36 while(~scanf("%d%d",&n,&m)){
37 for(int i=1;i<=n;i++){
38 scanf("%lld",&a[i]);
39 b[i]=a[i];
40 }
41 memset(dp,0,sizeof(dp));
42 sort(b+1,b+n+1);
43 len=unique(b+1,b+n+1)-b-1;
44 for(int i=1;i<=n;i++){
45 int pos=lower_bound(b+1,b+len+1,a[i])-b;
46 add(pos,1,1);
47 for(int j=2;j<=m;j++){
48 int sum=query(pos-1,j-1);
49 add(pos,j,sum);
50 }
51 }
52 printf("%lld\n",query(len,m));
53 }
54 return 0;
55 }

最新文章

  1. Python成长笔记 - 基础篇 (九)
  2. 关于alpha透明度
  3. Swift3.0语言教程字符串转换为数字值
  4. google快捷键,通过浏览器本身来查看
  5. windows7下使用telnet
  6. THD 变量存入threads中
  7. oracle 删除表、数据
  8. 阅读《RobHess的SIFT源码分析:综述》笔记2
  9. actionscript sendToURL请求url,传递http_referer分浏览器统计
  10. Google Code Jam Round 1A 2015 Problem B. Haircut 二分
  11. gitflow 在windows下的安装方法
  12. fastcgi_param 详解
  13. Gradle 1.12用户指南翻译——第五十三章. 签名插件
  14. vue 渲染后更新数据
  15. springboot整合多数据源及事物
  16. GPU并行的基础知识
  17. canvas+js+面向对象的圆形封装
  18. EF Core 2.1 支持数据库一对一关系
  19. poj1475 Pushing Boxes(BFS)
  20. [洛谷P3833][SHOI2012]魔法树

热门文章

  1. Netty-ProtobufVarint32
  2. zabbix监控添加学习笔记
  3. Nmap 操作手册 - 完整版
  4. Java8新特性: CompletableFuture详解
  5. 技术分析 | 浅谈在MySQL体系下SQL语句是如何在系统中执行的及可能遇到的问题
  6. CF859E 题解
  7. Linux系列之压缩命令
  8. Spring源码 20 手写模拟源码
  9. 根节点选择器和 html 选择器
  10. docker启动失败问题