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教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
随机推荐
- Protobuf入门实例
Protobuf是一个灵活.高效.结构化的数据序列化框架,相比于XML等传统的序列化工具, 它更小.更快.更简单.Protobuf支持数据结构化一次就可以到处使用,甚至是跨语言使用,通过代码生成工具可 ...
- WPF Combo box 获取选择的Tag
string str1 = ((ComboBoxItem)this.cboBoxRate1553B.Items[this.cboBoxRate1553B.SelectedIndex]).Tag.ToS ...
- 一些常用的页面js收集
//正则表达式 验证整数格式function checkInt(tint){ var re=/^[-]{0,1}[1-9]+[0-9]*]*$/; //判断字符串是否为数字 if (re.test(t ...
- css font-family(字体样式)
之前因为用的很少,所以没注意,最近做APP混合开发, 给字体一个样式 font-family:" 微软雅黑": 发现在有的手机上有效,但是在有的手机上是无效的, 解决方法: ...
- YouTube视频签名加密算法的破解
密码学方法 多年以前,YouTube的视频源地址是直接encode在页面中的,你甚至可以用一行Perl来下载它们. 直到2012年8月,这个简单的脚本(用在0.0.1版本的You-Get中)仍然可以解 ...
- 如果后台用framset框架布局,session过期,整个跳出回 登录页面的方法
如果session过期了,登录页面会在framset框架的右边显示,只能用 js 来做,让整个框架跳出去: 然而,这里 js 必须要用“top”才可以,作用是让整个framset都跳转,直接用 win ...
- Java: JavaMail 初试(一)
前言:以前的我,很喜欢写东西,写一写所想所见所闻所感,但是工作之后,总不能写出让自己满意的文章,突发奇想,能否利用写博客的时机,将其写成类似散文似的博文呢?哈哈... 邮件功能尝试:作为一个小菜鸟,对 ...
- 3.4-3.6 依据业务需求分析HBase的表设计
一.依据[话单]查询需求分析HBase的表设计 1.分析 用户需要进行实时的查询,那么这些数据是放在HBase当中的,每个客户每天接打电话至少20个左右,而通信公司拥有很多用户,每天产生的数据都是上亿 ...
- 【eclipse插件开发实战】Eclipse插件开发4——插件JDE、PDE开发方式及plugin.xml配置文件结构
Eclipse插件开发4--插件JDE.PDE开发方式及plugin.xml配置文件结构 开发方式分为:java开发环境JDE开发插件的方式和插件开发环境PDE开发插件方式. 插件通过添加到预定义的扩 ...
- 安全运维之关于个人ip定位与网站监控的分析
场景: 后台:有人盗刷我的短信接口.小偷偷我手机.无良黑客黑我网站 前台:发个欺骗链接或者说我在网上举报谁谁谁附带一个跳转url获取对方ip....... How to solve: ...