HDU 5542 - The Battle of Chibi - [离散化+树状数组优化DP]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5542
Problem Description
Cao Cao made up a big army and was going to invade the whole South China. Yu Zhou was worried about it. He thought the only way to beat Cao Cao is to have a spy in Cao Cao's army. But all generals and soldiers of Cao Cao were loyal, it's impossible to convince any of them to betray Cao Cao.
So there is only one way left for Yu Zhou, send someone to fake surrender Cao Cao. Gai Huang was selected for this important mission. However, Cao Cao was not easy to believe others, so Gai Huang must leak some important information to Cao Cao before surrendering.
Yu Zhou discussed with Gai Huang and worked out N information to be leaked, in happening order. Each of the information was estimated to has ai value in Cao Cao's opinion.
Actually, if you leak information with strict increasing value could accelerate making Cao Cao believe you. So Gai Huang decided to leak exact M information with strict increasing value in happening order. In other words, Gai Huang will not change the order of the N information and just select M of them. Find out how many ways Gai Huang could do this.
Input
The first line of the input gives the number of test cases, T(1≤100). T test cases follow.
Each test case begins with two numbers N(1≤N≤10^3) and M(1≤M≤N), indicating the number of information and number of information Gai Huang will select. Then N numbers in a line, the ith number ai(1≤ai≤10^9) indicates the value in Cao Cao's opinion of the ith information in happening order.
Output
For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the ways Gai Huang can select the information.
The result is too large, and you need to output the result mod by 1000000007(109+7).
Sample Input
2
3 2
1 2 3
3 2
3 2 1
Sample Output
Case #1: 3
Case #2: 0
Hint
In the first cases, Gai Huang need to leak 2 information out of 3. He could leak any 2 information as all the information value are in increasing order.
In the second cases, Gai Huang has no choice as selecting any 2 information is not in increasing order.
题意:
给出长度为 $N(1 \le N \le 10^3)$ 的数字序列(每个数字都在 $[1,10^9]$ 范围内)。
现在要从中挑选出长度为 $M(1 \le M \le N)$ 的严格单调递增子序列,问有多少种挑选方案。
题解:
首先,不难想到应当假设 $dp[i][j]$ 代表以 $a[i]$ 为结尾的且长度为 $j$ 的严格单增子序列的数目,
那么自然地,状态转移就是 $dp[i][j] = \sum dp[k][j-1]$,其中 $k$ 满足 $1 \le k < i$ 且 $a[k]<a[i]$。
不过,题目是不可能这么简单的……这样纯暴力dp的话时间复杂度为 $O(n^3)$,超时。
考虑进行优化:
先对 $dp$ 数组进行改造,假设 $dp[a_i][j]$ 代表:在数字序列的 $[1,i]$ 区间内,以数字 $a[i]$ 为结尾的长度为 $j$ 的严格单增子序列的数目,
这样一来,原来的 $a[i]$ 的范围在 $[1,10^9]$,数组是开不下的。所以,需要对 $a[1 \sim n]$ 先进行离散化,使得所有 $a[i]$ 的范围均在 $[1,n]$,这样数组就开的下了。
自然而然地,状态转移方程就变成了 $dp[a_i][j] = dp[1][j-1] + dp[2][j-1] + \cdots + dp[a_i-1][j-1]$。
然后,既然要优化求前缀和的速度,不妨对 $dp[1 \sim n][1]$ 构造一个树状数组,对 $dp[1 \sim n][2]$ 构造一个树状数组,$\cdots$,对 $dp[1 \sim n][m]$ 构造一个树状数组。
这样一来,我要求 $dp[1][j-1] + dp[2][j-1] + \cdots + dp[a_i-1][j-1]$ 这样一个前缀和就可以在 $O(\log n)$ 时间内完成。总时间复杂度变为 $O(n^2 \log n)$。
那么最后所求答案即为 $dp[1][m]+dp[2][m]+ \cdots + dp[n][m]$。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+;
const ll mod=1e9+; int n,m;
int a[maxn];
ll dp[maxn][maxn]; vector<int> v;
inline int getid(int x) {
return lower_bound(v.begin(),v.end(),x)-v.begin()+;
} inline int lowbit(int x){return x&(-x);}
void add(int pos,int len,ll val)
{
val%=mod;
while(pos<=n)
{
dp[pos][len]+=val;
dp[pos][len]%=mod;
pos+=lowbit(pos);
}
}
ll ask(int pos,int len)
{
ll res=;
while(pos>)
{
res+=dp[pos][len];
res%=mod;
pos-=lowbit(pos);
}
return res;
} int main()
{
int T;
cin>>T;
for(int kase=;kase<=T;kase++)
{
scanf("%d%d",&n,&m); v.clear();
for(int i=;i<=n;i++) scanf("%d",&a[i]), v.push_back(a[i]);
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
for(int i=;i<=n;i++) a[i]=getid(a[i]); memset(dp,,sizeof(dp));
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
if(j==) add(a[i],j,);
else
{
ll tmp=ask(a[i]-,j-);
add(a[i],j,tmp);
}
}
}
printf("Case #%d: %lld\n",kase,ask(n,m));
}
}
HDU 5542 - The Battle of Chibi - [离散化+树状数组优化DP]的更多相关文章
- HDU 6240 Server(2017 CCPC哈尔滨站 K题,01分数规划 + 树状数组优化DP)
题目链接 2017 CCPC Harbin Problem K 题意 给定若干物品,每个物品可以覆盖一个区间.现在要覆盖区间$[1, t]$. 求选出来的物品的$\frac{∑a_{i}}{∑b_ ...
- LUOGU P2344 奶牛抗议 (树状数组优化dp)
传送门 解题思路 树状数组优化dp,f[i]表示前i个奶牛的分组的个数,那么很容易得出$f[i]=\sum\limits_{1\leq j\leq i}f[j-1]*(sum[i]\ge sum[j- ...
- Codeforces 946G Almost Increasing Array (树状数组优化DP)
题目链接 Educational Codeforces Round 39 Problem G 题意 给定一个序列,求把他变成Almost Increasing Array需要改变的最小元素个数. ...
- 【题解】Music Festival(树状数组优化dp)
[题解]Music Festival(树状数组优化dp) Gym - 101908F 题意:有\(n\)种节目,每种节目有起始时间和结束时间和权值.同一时刻只能看一个节目(边界不算),在所有种类都看过 ...
- 【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)
[题解]ARC101F Robots and Exits(DP转格路+树状数组优化DP) 先删去所有只能进入一个洞的机器人,这对答案没有贡献 考虑一个机器人只能进入两个洞,且真正的限制条件是操作的前缀 ...
- Codeforces 909C Python Indentation:树状数组优化dp
题目链接:http://codeforces.com/contest/909/problem/C 题意: Python是没有大括号来标明语句块的,而是用严格的缩进来体现. 现在有一种简化版的Pytho ...
- BZOJ3594: [Scoi2014]方伯伯的玉米田【二维树状数组优化DP】
Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感 ...
- Codeforces 629D Babaei and Birthday Cake(树状数组优化dp)
题意: 线段树做法 分析: 因为每次都是在当前位置的前缀区间查询最大值,所以可以直接用树状数组优化.比线段树快了12ms~ 代码: #include<cstdio> #include< ...
- BZOJ 3594: [Scoi2014]方伯伯的玉米田 (二维树状数组优化DP)
分析 首先每次增加的区间一定是[i,n][i,n][i,n]的形式.因为如果选择[i,j](j<n)[i,j](j<n)[i,j](j<n)肯定不如把后面的全部一起加111更优. 那 ...
随机推荐
- 一道简单的HashMap面试题所想到的...
前言 看到一个JDK1.7和JDK1.8中关于HashMap的一个面试题: JDK1.7和1.8中HashMap中链表的插入的方式有什么不同? 原以为自己对HashMap的源码理解的还算可以了,应该足 ...
- 数据源从druid迁移到HikariCP
最近正好在做新项目,使用的是druid数据源,也真是巧,有朋友建议我使用HikariCP这个数据源,可以说是牛的一笔,速度快的飞起,性能极高! 要比druid不知道好多少倍,druid其实在某些情况下 ...
- 译:9.使用Redis进行消息传递
本指南引导您完成使用Spring Data Redis发布和订阅通过Redis发送的消息的过程.Messaging with Redis 1. 我们将构建什么? 您将构建一个使用StringRedis ...
- function 与 => 的区别
在JS中,箭头函数并不是简单的function(){}匿名函数的简写语法糖,实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,在编写函数时就已经确定了.而匿名函数的this ...
- Android截图命令screencap与视频录制命令screenrecord
Android截图命令screencap 查看帮助命令 bixiaopeng@bixiaopeng ~$ adb shell screencap -v screencap: invalid optio ...
- Django基础学习之Cookie 和 Sessions 应用
在Django里面,使用Cookie和Session看起来好像是一样的,使用的方式都是request.COOKIES[XXX]和request.session[XXX],其中XXX是您想要取得的东西的 ...
- 3D 特征点概述(1)
很久没有更新相关内容了,很多朋友过来私信我,但由于时间问题,不能一一为大家解答,本人也不是无所不知的大神,还请各位谅解. 本文主要总结PCL中3D特征点的相关内容,该部分内容在PCL库中都是已经集成的 ...
- Scala学习笔记(二):object、伴生对象和基本类
object object 是只有一个实例的类.它的定义与Java中的class类似,如: // 单例对象 object AppEntry { def main(args: Array[String] ...
- IOC容器特性注入第七篇:请求上下文作用域
Ninject的对象作用域: Transient .InTransientScope() 每次调用创建新实例. Singleton .InSingletonScope() 单例,仅创建一个实例. Th ...
- Linux权限详解 命令之 chmod:修改权限
权限简介 Linux系统上对文件的权限有着严格的控制,用于如果相对某个文件执行某种操作,必须具有对应的权限方可执行成功. Linux下文件的权限类型一般包括读,写,执行.对应字母为 r.w.x. Li ...