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更优. 那 ...
随机推荐
- Wifiner for Mac(WiFi 状况分析工具)破解版安装
1.软件简介 Wifiner 是 macOS 系统上一款 Wifi 分析工具,仅需几次点击即可对您的 Wi-Fi 网络连接进行分析和故障排除.扫描您的 Wi-Fi 网络,获取包含交互式彩色编码热 ...
- GraphQL,你准备好了么?
一个多月前,facebook 将其开源了一年多的 GraphQL 标记为 production ready ( http://graphql.org/blog/production-ready/ ), ...
- Hexo NexT 博客后台管理指南
上篇文章讲到,将Hexo NexT 博客成功上传到GitHub 并绑定到我们自定义的域名下了. 但是却还是有个问题,那就是Hexo NexT 博客如何进行后台管理呢? 如果总是通过手动创建文件的方式, ...
- Mac下软件包管理器-homebrew
类似于redhat系统的yum,ubuntu的apt-get,mac系统下也有相应的包管理容器:homebrew.用法与apt-get.yum大同小异,都是对安装软件做一些安装删除类的命令行操作,以下 ...
- 安装oracle遇到的故障
安装oracle遇到的故障 安装oracle遇到的故障总结 os:centos4.7(64位)db版本:oracle10.0.2.1(64位) 这次安装oracle又遇到点小问题,每次都是遇到点小问题 ...
- GitStack 第三方开源服务器端
GitStack 开源集成Git的界面服务器端 官网URL:http://gitstack.com 详情 请看<分布式版本控制系统Git--使用GitStack+TortoiseGi ...
- Gradle依赖的统一管理,解决依赖冲突
看见别人在用implementation rootProject.ext.dependencies["xxxx"]不知道是什么意思,上网查了一下,原来是为了解决或者说预防gradl ...
- /proc详解
内容摘要:Linux系统上的/proc目录是一种文件系统,即proc文件系统. Linux系统上的/proc目录是一种文件系统,即proc文件系统.与其它常见的文件系统不同的是,/proc是一种伪文件 ...
- H3C S5120清除console口密码
1.开机启动交换机显示Press Ctrl-B to enter Extended Boot menu...0 字样迅速按Ctrl-B进入如下字符介面提示: Press Ctrl-B to ente ...
- 10享元模式Flyweight
一.什么是享元模式 Flyweight模式也叫享元模式,是构造型模式之 一,它通过与其他类似对象共享数据来减小内存 占用. 二.享元模式的结构 三.享元模式的角色和职责 抽象享元角色: 所有具体享元类 ...