题目链接: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]的更多相关文章

  1. HDU 6240 Server(2017 CCPC哈尔滨站 K题,01分数规划 + 树状数组优化DP)

    题目链接  2017 CCPC Harbin Problem K 题意  给定若干物品,每个物品可以覆盖一个区间.现在要覆盖区间$[1, t]$. 求选出来的物品的$\frac{∑a_{i}}{∑b_ ...

  2. LUOGU P2344 奶牛抗议 (树状数组优化dp)

    传送门 解题思路 树状数组优化dp,f[i]表示前i个奶牛的分组的个数,那么很容易得出$f[i]=\sum\limits_{1\leq j\leq i}f[j-1]*(sum[i]\ge sum[j- ...

  3. Codeforces 946G Almost Increasing Array (树状数组优化DP)

    题目链接   Educational Codeforces Round 39 Problem G 题意  给定一个序列,求把他变成Almost Increasing Array需要改变的最小元素个数. ...

  4. 【题解】Music Festival(树状数组优化dp)

    [题解]Music Festival(树状数组优化dp) Gym - 101908F 题意:有\(n\)种节目,每种节目有起始时间和结束时间和权值.同一时刻只能看一个节目(边界不算),在所有种类都看过 ...

  5. 【题解】ARC101F Robots and Exits(DP转格路+树状数组优化DP)

    [题解]ARC101F Robots and Exits(DP转格路+树状数组优化DP) 先删去所有只能进入一个洞的机器人,这对答案没有贡献 考虑一个机器人只能进入两个洞,且真正的限制条件是操作的前缀 ...

  6. Codeforces 909C Python Indentation:树状数组优化dp

    题目链接:http://codeforces.com/contest/909/problem/C 题意: Python是没有大括号来标明语句块的,而是用严格的缩进来体现. 现在有一种简化版的Pytho ...

  7. BZOJ3594: [Scoi2014]方伯伯的玉米田【二维树状数组优化DP】

    Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感 ...

  8. Codeforces 629D Babaei and Birthday Cake(树状数组优化dp)

    题意: 线段树做法 分析: 因为每次都是在当前位置的前缀区间查询最大值,所以可以直接用树状数组优化.比线段树快了12ms~ 代码: #include<cstdio> #include< ...

  9. BZOJ 3594: [Scoi2014]方伯伯的玉米田 (二维树状数组优化DP)

    分析 首先每次增加的区间一定是[i,n][i,n][i,n]的形式.因为如果选择[i,j](j<n)[i,j](j<n)[i,j](j<n)肯定不如把后面的全部一起加111更优. 那 ...

随机推荐

  1. maven本地库与私服比对,查找缺失jar包

    项目中遇到的一个问题,因为要切换开发环境(新环境不能联网,且私服上的jar包信息不全),需要将本地仓库(项目使用本地仓库能够正常编译)中有而私服上没有的jar包整理出来(名称.版本号等),提供给第三方 ...

  2. 【Unity笔记】打包安卓APK时Build Setting中的三种Build System

    Internal(Default):Unity内置,仅需Android SDK支持.不能导出工程,适用于仅适用Unity开发的工程. Gradle(New):使用Gradle进行构建,需要Androi ...

  3. 微信mac版的bug 直接显示了消息原始数据

    <msg> <voicemsg endflag="1" cancelflag="0" forwardflag="0" vo ...

  4. ubuntu下使用golang、qml与ubuntu sdk开发桌面应用 (简单示例)

    找了很长时间go的gui库,试了gtk,准备试qt的时候发现了这个qml库,试了下很好用. ##准备工作 **1.Go 1.2RC1** go的版本应该不能低于这个,我是在1.2RC发布当天升级后发现 ...

  5. AI金融知识自学偏量化方向-了解不同类型的机器学习2

    有监督学习 vs 无监督学习 迭代和评估 偏差方差权衡 结合有监督学习和无监督学习(半监督学习)

  6. js 上一步 下一步 操作

    <a id="syb" href="#" style="display: block;" class="btn button ...

  7. 执行start-dfs.sh后,datenode没有启动的解决办法

    执行start-dfs.sh后,datenode没有启动,很大一部分原因是因为在第一次格式化dfs后,启动并使用了hadoop,后来又重新执行了格式化命令(hdfs namenode -format) ...

  8. linux下用/proc/stat文件来计算cpu的利用率-c语言实现

    proc文件系统介绍 /proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以文件系统的方式为内核与进程提供通信的接口.用户和应用程序可以通过/proc得到系统的信息,并可以改变内 ...

  9. win 停止tomcat

    1.首先查找到占用8080端口的进程号PID是多少 CMD>netstat -ano | findstr 8080 这个命令输出的最后一列表示占用8080端口的进程号是多少,假设为1234 2. ...

  10. VMware Workstation11安装Mac OS X 10.10虚拟机

    原文:http://jingyan.baidu.com/article/3f16e003eac66e2591c103e0.html 优化:http://www.cnblogs.com/yipu/p/4 ...