HDU5542 BIT优化dp
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的更多相关文章
- bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)
题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)
D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
- [BZOJ3156]防御准备(斜率优化DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP
- 【BZOJ-1096】仓库建设 斜率优化DP
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3719 Solved: 1633[Submit][Stat ...
- 优化DP的奇淫技巧
DP是搞OI不可不学的算法.一些丧心病狂的出题人不满足于裸的DP,一定要加上优化才能A掉. 故下面记录一些优化DP的奇淫技巧. OJ 1326 裸的状态方程很好推. f[i]=max(f[j]+sum ...
- 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 ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
随机推荐
- 只要访问url地址 那么容器就会根据地址进行对象的创建
只要访问url地址 那么容器就会根据地址进行对象的创建
- C 语言-----字符串和输入输出函数
在C语言中,没有字符串类型,那它是怎么表示字符串呢? 由于字符串是一系列单个字符的组合,所以它用char 类型的数组来表示字符串,在数组中,一个数组元素存放一个char类型字符. ]; name 变量 ...
- codeforces467C
George and Job CodeForces - 467C The new ITone 6 has been released recently and George got really ke ...
- THEKEY
追溯历史,有据可查的身份证明是中国隋唐时期的“鱼符”,只为达官贵人证明身份等级,后演变为“龟符”.“牙牌”.“腰牌”等,直至近现代时期才出现真正意义的身份证,增加了个人信息描述.由于过去的生产力水平较 ...
- js判断一个元素是否在数组中
js判断一个元素是否在数组中 var arr = ['a','s','d','f']; console.info(isInArray(arr,'a'));//循环的方式 function isInAr ...
- python史上最全学习路线图
ps:盘它 python入门教程 关注微信公众号,回复"python入门"获取视频下载地址
- Android app下载并安装
1 下载功能 //下载apk private void downloadApk(String apkUrl) throws PackageManager.NameNotFoundException ...
- 查询SQL磁盘活动量信息
/* 用来显示有关由 Transact-SQL 语句生成的磁盘活动量的信息.*/DBCC DROPCLEANBUFFERS --清空缓存set statistics io on --开启set sta ...
- 牛客寒假算法训练1 D 欧拉(容斥)
1 #include<bits/stdc++.h> using namespace std; ; typedef long long ll; int p[maxn],a[maxn]; ll ...
- flowable6.4.1+springboot使用dmn
resources/dmn/strings_1.dmn <?xml version="1.0" encoding="UTF-8"?> <def ...