http://acm.hdu.edu.cn/showproblem.php?pid=5542

题意:求严格递增的长度为M的序列的组数。

当dp的优化方案不那么容易一眼看出来的时候,我们可以考虑先写一个朴素算法,在朴素算法的基础上去考虑优化。

正如这题,很显然用dp[i][j]存储长度为i的序列以j结尾的情况。

然后有两种方法去递推。

一种是从1--M序列的长度,对于每一个数字去寻找他前面比她小的数列进行递推,递推方程dp[i][j] += dp[i - 1][k]; (k < j && a[k] < a[j])

第二种方法是从1--N枚举每个数,对于每个数直接寻找他前面的所有满足上面k条件的数字进行递推。

两种方法时间复杂度相同,朴素算法都是T * M * N * N,显然会TLE,但是考虑在其中一层,也就是寻找他前面枚举条件的数这一步进行优化,当我们用树状数组维护前缀的和的时候,我们就可以把一层N优化变为lnN,总的时间复杂度变成O(TNMln(N));

        For(i,,M){
Mem(tree,);
if(i == ) add(,);
For(j,,N){
dp[i & ][j] = getsum(a[j] - ) % mod;
add(a[j],dp[i + & ][j]);
}
}

第一种方法的主要优化代码

    For(i,,N){
For(j,,M){
if(j == ) dp[j & ][i] = ;
else dp[j & ][i] = getsum(j - ,a[i] - ) % mod;
add(j,a[i],dp[j & ][i]);
}
}

第二种方法的主要优化代码

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
const double eps = 1e-;
const int maxn = ;
const LL INF = 1e18;
const int mod = 1e9 + ;
int N,M,tmp,K;
LL a[maxn];
int cnt;
LL Hash[maxn];
inline LL read()
{
LL now=;register char c=getchar();
for(;!isdigit(c);c=getchar());
for(;isdigit(c);now=now*+c-'',c=getchar());
return now;
}
LL dp[][maxn];
LL tree[maxn];
void add(int x,LL t){
for(;x <= cnt + ; x += x & -x) tree[x] = (tree[x] + t) % mod;
}
LL getsum(int x){
LL s = ;
for(;x > ;x -= x & -x) s = (s + tree[x]) % mod;
return s;
}
int main()
{
int T; Sca(T);
int CASE = ;
while(T--){
Sca2(N,M);
For(i,,N) Hash[i] = a[i] = read();
sort(Hash + ,Hash + + N);
cnt = unique(Hash + ,Hash + + N) - Hash - ;
For(i,,N) a[i] = lower_bound(Hash + ,Hash + + cnt,a[i]) - Hash + ;
Mem(dp,);
For(i,,M){
Mem(tree,);
if(i == ) add(,);
For(j,,N){
dp[i & ][j] = getsum(a[j] - ) % mod;
add(a[j],dp[i + & ][j]);
}
}
LL ans = ;
For(i,,N) ans = (ans + dp[M & ][i]) % mod;
printf("Case #%d: ",CASE++);
Prl(ans);
}
#ifdef VSCode
system("pause");
#endif
return ;
}

HDU5542 BIT优化dp的更多相关文章

  1. bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)

    题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...

  2. bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)

    题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...

  3. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  4. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  5. [BZOJ3156]防御准备(斜率优化DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP

  6. 【BZOJ-1096】仓库建设 斜率优化DP

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3719  Solved: 1633[Submit][Stat ...

  7. 优化DP的奇淫技巧

    DP是搞OI不可不学的算法.一些丧心病狂的出题人不满足于裸的DP,一定要加上优化才能A掉. 故下面记录一些优化DP的奇淫技巧. OJ 1326 裸的状态方程很好推. f[i]=max(f[j]+sum ...

  8. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

  9. BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP

    1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...

随机推荐

  1. July 算法习题 - 字符串4(全排列和全组合)

    https://segmentfault.com/a/1190000002710424 思想:当前层各节点首元素不同,则各节点的剩余元素也不同:下一层节点交换范围为首元素以外的元素 全排列算法: vo ...

  2. DatasourceUtils类:获取连接池和数据库连接

    本工具类用于获取连接池和数据库连接 package com.itheima.utils; import java.sql.Connection; import java.sql.ResultSet; ...

  3. Nginx 模块分类

    L:34

  4. Nginx http2.0

    109/110 HTTP2.0协议 优势必须使用TLS加密 传输数据量大幅减少 1:以二进制格式传输  2:标头压缩(header做压缩) 多路复用及相关功能 : 消息优先级 (比如样式表先渲染页面那 ...

  5. 洛谷P2084 进制转换

    题目背景 无 题目描述 今天小明学会了进制转换,比如(10101)2 ,那么它的十进制表示的式子就是 : 1*2^4+0*2^3+1*2^2+0*2^1+1*2^0, 那么请你编程实现,将一个M进制的 ...

  6. Educational Codeforces Round 53 (Rated for Div. 2) C. Vasya and Robot

    题意:给出一段操作序列 和目的地 问修改(只可以更改 不可以删除或添加)该序列使得最后到达终点时  所进行的修改代价最小是多少 其中代价的定义是  终点序号-起点序号-1 思路:因为代价是终点序号减去 ...

  7. Appium环境的安装以及一路上的坑

    Appium环境的安装以及一路上的坑 第一步环境的安装 l  javaJDK的安装以及环境变量的配置这个我就不说了网上的教程全都是,搜一个安装一下吧 l  AndroidSDK的安装也是如此我是直接安 ...

  8. PHP 事务写法

    $md=new Model(); //创建事务 $md->startTrans(); //开始事务 $md->table("ym_xxx")->where(&qu ...

  9. 【BZOJ2618】[CQOI2006]凸多边形(半平面交)

    [BZOJ2618][CQOI2006]凸多边形(半平面交) 题面 BZOJ 洛谷 题解 这个东西就是要求凸多边形的边所形成的半平面交. 那么就是一个半平面交模板题了. 这里写的是平方的做法. #in ...

  10. 【转】STM32擦除内部FLASH时间过长导致IWDG复位分析

    @20119-01-29 [小记] STM32擦除内部FLASH时间过长导致IWDG复位分析