The Battle of Chibi

Time Limit: 6000/4000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 2899    Accepted Submission(s): 1043

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≤103) 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≤109) 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.

 
Source
 
Recommend
wange2014   |   We have carefully selected several similar problems for you:  6447 6446 6445 6444 6443 

题意:

问一个序列之中有多少个长度为M的严格递增子序列。

思路:

我们用dp[i][j]表示前j个数中,以Aj为结尾的长度为i的严格递增子序列的个数。

那么对于dp[i][j],我们只需要枚举所有小于j的k,并且Ak < Aj,将所有的dp[i-1][k]求和,可以得到dp[i][j]

很容易想到O(n^3)的算法,但是显然会超时,所以我们需要进行一些优化。

当我们枚举内层循环j,k时,外层循环i就可以被当成是定值。当j增加1,k的取值只是多了k = j这个新的决策。

因此我们用树状数组维护一个前缀和,表示1~j区间,长度为i-1时的方案数。

由于add时第一个参数放的是a[j],也就是说现在直接用了他的权值作为了下标,所以只要下标比他小的,权值一定比他小,也就不需要进行比较了。直接去前缀和就可以了。【日常感谢家庭教师】

最开始离散化用的set和map TLE了

后来改用了另一个数组,先排序然后lower_bound,并且直接把原数组的值改掉

 #include <iostream>
#include <set>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
#define inf 0x7f7f7f7f int t, n, m, cnt;
const int maxn = ;
const LL mod = 1e9 + ;
int a[maxn], b[maxn];
LL sum[maxn], dp[maxn][maxn];
map<LL, int>discrete;
set<LL>sss;
set<LL>::iterator iter; void add(int pos, LL x)
{
while(pos <= n + ){
sum[pos] = (sum[pos] + x) % mod;
pos += (pos & -pos);
}
} LL ask(int pos)
{
LL ans = ;
while(pos){
ans = (ans + sum[pos]) % mod;;
pos -= (pos & -pos);
}
return ans;
} void init()
{
discrete.clear();
sss.clear();
//memset(dp, 0, sizeof(dp));
for(int i = ; i <= m; i++){
for(int j = ; j <= n; j++){
dp[i][j] = ;
}
}
cnt = ;
} int main()
{
scanf("%d", &t);
for(int cas = ; cas <= t; cas++){
init();
scanf("%d%d", &n, &m);
a[] = b[] = -inf;
dp[][] = ;
//sss.insert(a[0]);
for(int i = ; i <= n; i++){
scanf("%d", &a[i]);
b[i] = a[i];
//sss.insert(a[i]);
}
sort(b, b + n + );
for(int i = ; i <= n; i++){
a[i] = lower_bound(b, b + + n, a[i]) - b + ;
//cout<<a[i]<<endl;
}
/*for(iter = sss.begin(); iter != sss.end(); iter++){
discrete[*iter] = ++cnt;
}*/
//cout<<a[0]<<endl;
for(int i = ; i <= m; i++){
//memset(sum, 0, sizeof(sum));
for(int j = ; j <= n + ; j++){
sum[j] = ;
}
add(a[], dp[i - ][]); for(int j = ; j <= n; j++){
dp[i][j] = ask(a[j] - );
//if(discrete[a[j]] < discrete[a[j + 1]])
add(a[j], dp[i - ][j]);
}
} int ans = ;
for(int i = ; i <= n; i++){
ans = (ans + dp[m][i]) % mod;
}
printf("Case #%d: %d\n", cas, ans);
}
}

hdu5542 The Battle of Chibi【树状数组】【离散化】的更多相关文章

  1. 南阳ccpc C题 The Battle of Chibi && hdu5542 The Battle of Chibi (树状数组优化+dp)

    题意: 给你一个长度为n的数组,你需要从中找一个长度为m的严格上升子序列 问你最多能找到多少个 题解: 我们先对原序列从小到大排序,排序之后的序列就是一个上升序列 这里如果两个数相等的话,那么因为题目 ...

  2. 南阳ccpc C题 The Battle of Chibi 树状数组+dp

    题目: Cao Cao made up a big army and was going to invade the whole South China. Yu Zhou was worried ab ...

  3. hdu4605 树状数组+离散化+dfs

    Magic Ball Game Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  4. BZOJ_5055_膜法师_树状数组+离散化

    BZOJ_5055_膜法师_树状数组+离散化 Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然 ...

  5. POJ 2299 【树状数组 离散化】

    题目链接:POJ 2299 Ultra-QuickSort Description In this problem, you have to analyze a particular sorting ...

  6. HDU 2227 Find the nondecreasing subsequences (DP+树状数组+离散化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2227 Find the nondecreasing subsequences             ...

  7. BZOJ-1227 虔诚的墓主人 树状数组+离散化+组合数学

    1227: [SDOI2009]虔诚的墓主人 Time Limit: 5 Sec Memory Limit: 259 MB Submit: 914 Solved: 431 [Submit][Statu ...

  8. POJ 2299 树状数组+离散化求逆序对

    给出一个序列 相邻的两个数可以进行交换 问最少交换多少次可以让他变成递增序列 每个数都是独一无二的 其实就是问冒泡往后 最多多少次 但是按普通冒泡记录次数一定会超时 冒泡记录次数的本质是每个数的逆序数 ...

  9. [HDOJ4325]Flowers(树状数组 离散化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4325 关于离散化的简介:http://blog.csdn.net/gokou_ruri/article ...

  10. HDU4456-Crowd(坐标旋转+二位树状数组+离散化)

    转自:http://blog.csdn.net/sdj222555/article/details/10828607 大意就是给出一个矩阵 初始每个位置上的值都为0 然后有两种操作 一种是更改某个位置 ...

随机推荐

  1. C# winform 获取当前路径

    // 获取程序的基目录. System.AppDomain.CurrentDomain.BaseDirectory// 获取模块的完整路径.System.Diagnostics.Process.Get ...

  2. 转载:QT QTableView用法小结

    出自: http://blog.chinaunix.net/uid-20382483-id-3518513.html QTableView常用于实现数据的表格显示.下面我们如何按步骤实现学生信息表格: ...

  3. R语言低级绘图函数-axis

    axis函数用来在一张图表上添加轴线,区别于传统的x轴和y轴,axis 允许在上,下,左, 右4个方向添加轴线 以x轴为例,一条轴线包含3个元素,水平的一条横线,叫做axis line , 刻度线, ...

  4. 根据多表条件更新表.............. 一条sql语句.............

    CREATE TABLE a( NAME INT, age int ); CREATE TABLE b( height INT, weight int ); ,); ,); SELECT * FROM ...

  5. Windows 上 GitHub Desktop 的操作[转]

    第1章 上传开源代码至GitHub    1 1.1 git Windows 客户端    1 1.2 注册GitHub账户    2 1.3 登录    2 1.4 创建本地代码仓库    2 1. ...

  6. 【C++基础 05】友元函数和友元类

    友元是一种定义在类外部的普通函数或类,但它须要在类体内进行说明,为了与该类的成员函数加以差别,在说明时前面加以keywordfriend. 友元不是成员函数,可是它能够訪问类中的私有成员. 友元的作用 ...

  7. git 分支的创建、合并、删除

          基本概念与命令 分支(branch):每次提交,Git都把提交的内容串成一条时间线,这条时间线就是一个分支 .   git 分支的创建 git branch branchName git ...

  8. Unity战斗系统之AI自主决策

    http://www.taikr.com/course/448/tasks http://www.xuanyusong.com/archives/1840 http://www.cnblogs.com ...

  9. BDIP和BVLC纹理分析

    Young Deok Chun 等人提出了基于 BVLC 矩和 BDIP 矩的一种纹理分析方法.BVLC 能显示粗糙和光滑特性,BDIP 能够很好的提取波谷和边缘.它们直接在彩色空间上进行处理,能有效 ...

  10. swift - UITextView的用法

    1,多行文本控件的创建 textView.frame = CGRect(x:50,y:180,width:self.view.bounds.size.width - 100,height:50) te ...