wmq的队伍 BIT优化dp
http://oj.xjtuacm.com/problem/14/
wmq的队伍
发布时间: 2017年4月9日 17:06 最后更新: 2017年4月9日 17:07 时间限制: 2000ms 内存限制: 512M
交大上课需要打卡,于是在上课前的几分钟打卡机前往往会排起长队。
平时早睡早起早早打卡的wmq昨晚失眠,今天起晚了,于是他也加入了打卡队伍中。
这个时候,wmq发现了神奇的现象,打卡队伍可以按人们的身高看成一个队列,左边是队头,右边是队尾。
对于队列a1...an,wmq想知道其中存在多少的有序k元组l1...lk
使得1≤l1<l2<...<lk≤n,并且有al1>al2>...>alk
输入有多组数据
第一行是一个正整数T,1≤T≤15,代表数据组数
每组数据第一行是两个正整数n,k,1≤n≤2∗104,1≤k≤min(n,100)
n代表队列的人数,k 的含义见题面
接下来一行有n个正整数,代表1到n的一个排列,表示队伍的身高情况
对于每组数据,输出一个整数,代表有序k元组的个数
考虑到数字可能很大,将答案对109+7取模之后输出
3
2 2
1 2
2 2
2 1
22 3
1 2 3 4 5 16 6 7 8 9 10 19 11 12 14 15 17 18 21 22 20 13
0
1
8
这题是一眼看破的题了,设dp[i][k]表示以第i个数字结尾的时候,下降子序列长度为k时的种类数。
那么dp[i][k] = sigma dp[res][k - 1],a[res] > a[i], 1 <= res <= i - 1
那么答案就是 sigma dp[i][k], 1 <= i <= n
然后发现这样会超时,就马上否认了这个做法。于是做了3小时。
其中有一种比较有趣的想法是考虑每一个数字贡献,以
4、3、2、1,k = 3为例子。算出每一个位置的逆序对数,那么对于每一个点,如果它的逆序对 + 1 >= k的,就可以作为贡献
也就是,比如2的逆序对有2对,那么加上2就形成一个长度为3的下降子序列,这个时候有C(2, 2) = 1种,意思就是不包括2的话,我还要选出k - 1 = 2个数字,形成长度是3的下降子序列。那么1的逆序对有3种,贡献是C(3, 2) = 3种,最后ans = 4是对的。
这个方法思路很清晰,也很好理解,是bit + 组合数学,意思就是在前面m个数字选出k - 1个,形成长度是k的子序列。
但是这里忽略了16、19、11,k = 3这样的情况,因为虽然11的逆序对是2,能对答案造成贡献,但是这里11的逆序对互相不能形成逆序对。所以这样的做法是不行的。
然后设了很多dp,发现还是这个能做。暴力了一下,这个dp是正确的。
然后就是怎么优化了。
希望复杂度是O(nk)
那么我就需要快速知道,前i个数,有多少个比a[i]大的数字,而且它们产生的下降子序列长度是k。的总和
bit数组c[k]维护的是下降子序列长度是k时的数字情况。
具体看看代码。以后写出一个合法的dp,超时的,优化下,想一想有没什么数据结构或者某一维是并不需要关心的,比如浙大的校赛那题。dp就是带技巧的暴力,
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = + ;
int dp[maxn][ + ];
int a[maxn];
int c[ + ][maxn];
int n, k;
const int MOD = 1e9 + ;
void add(int &x, int val) {
x += val;
if (x >= MOD) x -= MOD;
}
int lowbit(int x) {
return x & (-x);
}
void upDate(int pos, int val, int which) {
while (pos) {
add(c[which][pos], val);
pos -= lowbit(pos);
}
}
int ask(int pos, int which) {
int ans = ;
while (pos <= n) {
add(ans, c[which][pos]);
pos += lowbit(pos);
}
return ans;
}
void work() {
scanf("%d%d", &n, &k);
memset(c, , sizeof c);
memset(dp, , sizeof dp);
for (int i = ; i <= n; ++i) {
scanf("%d", &a[i]);
}
for (int i = ; i <= n; ++i) {
dp[i][] = ;
for (int j = ; j <= k; ++j) {
add(dp[i][j], ask(a[i] + , j - ));
}
for (int j = ; j <= k; ++j) {
upDate(a[i], dp[i][j], j);
}
}
int ans = ;
for (int i = ; i <= n; ++i) {
add(ans, dp[i][k]);
}
printf("%d\n", ans);
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
// cout << comb[7][2] << endl;
// cout << comb[4][2] << endl;
int t;
scanf("%d", &t);
while (t--) work();
return ;
}
wmq的队伍 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教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
随机推荐
- H264 各种profile
关键字:H264 ,base profile, main profile, extend profile, high profile. 提到High Profile H.264解码许多人并不了解,那么 ...
- codeforces 665B B. Shopping(水题)
题目链接: B. Shopping time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- hdu-5000 Clone(dp)
题目链接: Clone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Pro ...
- ubuntu熟悉过程中遇到一些小问题记录一下
0. 使用su命令时提示: authentication failur 安装ubuntu系统默认是没有激活root用户的,需要我们手工进行操作,在命令行界面下,或者在终端中输入如下命令:sudo p ...
- Android开发者的四大工具
1. Basic4Android Basic4Android是Android平台上一个简单而又强大的可视化快速应用开发工具,它可被用来开发和测试数据库通信,甚至可以被用来开发2D的即时游戏! 主要特性 ...
- html格式
优美的代码编写方式是我们装逼的基础,在python中我们称优秀的代码为pythonic,无独有偶,html.css.js也都有着自己相比更优美的写法~ <!DOCTYPE html> &l ...
- 二Java的常量与变量-1-1标识符
类的名字就是标识符 起类名也是不能带空格的
- UVaLive 6847 Zeroes (找规律,水题)
题意 :给定一个范围,然后让你求在这个范围内所有的数的阶乘末尾0的个数有多少种. 析:找规律,写几个就会发现每隔5个会增加一个0,因为要么乘10了,要么乘5了. 代码如下: #pragma comme ...
- CodeForces - 377A Maze BFS逆思维
Maze Pavel loves grid mazes. A grid maze is an n × m rectangle maze where each cell is either empty, ...
- 已有项目 iPhoneX 适配
一.Assets 文件图片管理下的 LaunchImage 添加 iOS8.0 and latter 一项,并放一张 1125*2436 的LaunchPage 到对应的位置上. 二.有关 iPhon ...