3193: [JLOI2013]地形生成


Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 459  Solved: 223
[Submit][Status][Discuss]

Description


 
 
最近IK正在做关于地形建模的工作。其中一个工作阶段就是把一些山排列成一行。每座山都有各不相同的标号和高度。为了遵从一些设计上的要求,每座山都设置了一个关键数字,要求对于每座山,比它高且排列在它前面的其它山的数目必须少于它的关键数字。
 显然满足要求的排列会有很多个。对于每一个可能的排列,IK生成一个对应的标号序列和等高线序列。标号序列就是按顺序写下每座山的标号。等高线序列就是按顺序写下它们的高度。例如有两座山,这两座山的一个合法排列的第一座山的标号和高度为1和3,而第二座山的标号和高度分别为2和4,那么这个排列的标号序列就是1 2,而等高线序列就是3 4.
 现在问题就是,给出所有山的信息,IK希望知道一共有多少种不同的符合条件的标号序列和等高线序列。
 

Input


输入第一行给出山的个数N。接下来N行每行有两个整数,按照标号从1到N的顺序分别给出一座山的高度和关键数。
 

Output


 
输出两个用空格分隔开的数,第一个数是不同的标号序列的个数,第二个数是不同的等高线序列的个数。这两个答案都应该对2011取模,即输出两个答案除以2011取余数的结果
 

Sample Input



Sample Output


 

HINT


对于所有的数据,有1<=N<=1000,所有的数字都是不大于109的正整数。

分析:


先考虑第一个问题(先假设没有山高度相同):

我们把所有山按高度从大到小排序,设这个集合为S,设一个空集合为V。

我们把山按顺序放入集合V。

考虑第i座山放进去的时候能放的位置,因为现在前面有i - 1座山比它高,再加上本来的第i个位置,它一共有i个位置可以放。这个山的关键值如果为k,它只能在前min(k,i)个位置里挑。

所以第i个山的放的位置的组合为ci = min(k,i)种。ans = c1 * c2 …… * cn;

但是我们现在有山的高度相同,且关键值不同。两座高度相同的山能放的最靠后的位置,一定是关键值大的那个越靠后。所以我们先按高度从大到小,然后高度相同的关键值从小到大排序出S集合。

设[x,y]这段区间的山高度相同。所以 ci = min(x,k) + i - num。因为一座山在满足关键值的情况下,可以也放在高度相同的山前面。

所以最后 得出 ans1 = c1 * c2 …… * cn;

然后再看第二个问题,会产生重复情况的只有高度相同的山放一起的情况。

我们依然排序出V集合。按顺序插入山。

定义dp状态f[i][j],表示高度相同的山里面前i座,放在前j个位置的方案数。

因为我们是插入的山,比如说在一座高度为3的山后面再插入一座高度为3的山,此时是多了一种方案,是不会重复的。

状态也是很好转移设区间[x,y]山高度相同

f[i][j] = sum(f[i - 1][k] );k <= min(data[i].d,x) - 1;

因为是按顺序来刷表的可以省掉一维。

又因为f[i][j - 1] = sum(f[i][j - 1]);f[i][j] = sum(f[i - 1][k] );k <= min(data[i - 1].d,x) - 1;所以f[i][j] = f[i - 1][j] + f[i][j - 1]

最终方程dp[i] = dp[i - 1] + dp[i]

最后把每一区间[x,y]相同的山的ci = dp[0] + dp[1] +……dp[min(data[y].d,x) - 1]乘起来。

ans2 = c1 * c2 …… * cn;

就可以了。

AC代码:


# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
using namespace std;
const int mod = ;
const int N = ;
int dp[N],h[N],n,ans1 = ,ans2 = ;
struct Mountain{
int h;
int d;
bool operator <(const Mountain & other)const{
if(h == other.h)return d < other.d;
return h > other.h;
}
}data[N];
void Init(){
memset(dp,,sizeof dp);
dp[] = ;
}
void read(){
scanf("%d",&n);
for(int i = ;i <= n;i++){
scanf("%d %d",&data[i].h,&data[i].d);
}
sort(data + ,data + n + );
int num = ;
for(int i = ;i <= n;i++){
if(data[i].h != data[num].h)num = i;
(ans1 *= min(num,data[i].d) + i - num) %= mod;
}
printf("%d",ans1);
}
void work(){
int pos;
for(int i = ;i <= n;i++){
pos = i;
while(data[pos].h == data[i].h && pos <= n)pos++;
pos--;Init();
for(int j = i;j <= pos;j++){
for(int k = ;k <= min(data[j].d,i) - ;k++){
(dp[k] = dp[k - ] + dp[k]) %= mod;
}
}
int sum = ;
for(int j = ;j <= min(data[pos].d,i) - ;j++)(sum += dp[j]) %= mod;
(ans2 *= sum) %= mod;
i = pos;
}
printf(" %d\n",ans2);
}
int main()
{
read();
work(); }

[Bzoj3193][JLOI2013]地形生成 (排列组合 + DP)的更多相关文章

  1. [bzoj3193][JLOI2013]地形生成_排列组合_贪心

    [JLOI2013]地形生成 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3193 题解: 这种求总排列的题,一种常规做法就是所有的元素 ...

  2. BZOJ3193 [JLOI2013]地形生成 【dp】

    题目链接 BZOJ3193 题解 注意\(key\)是小于 第一问,显然按高度降序排序,逐个插入 如果高度各不相同,那么之前插入的都比当前插入的\(i\)大,可插入的位置个数就确定了 由于存在高度相同 ...

  3. BZOJ3193: [JLOI2013]地形生成

    传送门 Sol 第一问可以考虑按照山的高度从大到小放 但是这样如果遇到高度相同的就不好考虑,那么同时要求数量限制从小到大 这样每次放的时候后面的一定不会影响前面,并且高度相同的时候前面能放的位置后面的 ...

  4. BZOJ 3193: [JLOI2013]地形生成 计数 + 组合 + 动态规划

    第一问: 先不考虑山的高度有相同的:直接按照高度降序排序,试着将每一座山插入到前面山的缝隙中. 当然,这并不代表这些山的相对位置是固定的,因为后面高度更低的山是有机会插入进来的,所以就可以做到将所有情 ...

  5. 【BZOJ3193】 [JLOI2013]地形生成

    BZOJ3193 [JLOI2013]地形生成 Solution 第一问不是很简单吗? 直接计数就好了. 第二问思考无果看了看hyj神仙的代码,发现可以dp求解. 具体可以看代码(其实主要是我说不清楚 ...

  6. 【BZOJ3193】[JLOI2013]地形生成 DP

    [BZOJ3193][JLOI2013]地形生成 Description 最近IK正在做关于地形建模的工作.其中一个工作阶段就是把一些山排列成一行.每座山都有各不相同的标号和高度.为了遵从一些设计上的 ...

  7. 【BZOJ3193】[JLOI2013]地形生成(动态规划)

    [BZOJ3193][JLOI2013]地形生成(动态规划) 题面 BZOJ 洛谷 题解 第一问不难,首先按照山的高度从大往小排序,这样子只需要抉择前面有几座山就好了.然而有高度相同的山.其实也不麻烦 ...

  8. [JLOI2013]地形生成[组合计数]

    题意 \(n\) 元素各有一个高度 \(h\) 和关键数字 \(b\) .求有多少个下标序列和高度序列,满足对任意 \(i\),\(j< i\) 且 \(h_j < h_i\)的 \(j\ ...

  9. [JLOI2013]地形生成

    JLOI2013过了好长时间,才写第四题.. 第一问比较好想. 第二问我想到了n^3次方的做法,但是数据....于是没敢写,然后上网查了一下题解,居然是O(n^3)过的,数据这么弱... /* * P ...

随机推荐

  1. codevs 2761 脏话过滤

    时间限制: 1 s  空间限制: 8000 KB  题目等级 : 白银 Silver   题目描述 Description 某论坛希望打造文明论坛,对于每个帖子需要将脏话换成*输出. 脏话有38,25 ...

  2. slides 在线ppt && React && Angular

    现在主流前端框架 有3个 Vue React Angular 如果有时间就都学习,理解一下他们的差异性~ 在线ppt的一个网站 这个是npm讲解的,不错 https://slides.com/seld ...

  3. 任务一:零基础HTML编码

    面向人群: 零基础或初学者 难度: 简单 重要说明 百度前端技术学院的课程任务是由百度前端工程师专为对前端不同掌握程度的同学设计.我们尽力保证课程内容的质量以及学习难度的合理性,但即使如此,真正决定课 ...

  4. HDU-1297-Children’s Queue

    Children’s Queue 这道题是排序问题,可以用递归方法解决. 计算F(n): 一:当最后一个是男孩M时候,前面n-1个随便排出来,只要符合规则就可以,即是F(n-1): 二:当最后一个是女 ...

  5. excel组装sql

    ="INSERT INTO TABLE_XXXX (COLUMN_1, COLUMN_2, COLUMN_3, COLUMN_4, COLUMN_5, COLUMN_6, COLUMN_7, ...

  6. centos7.x设置静态IP

    本教程以centOs7.4为例: 1.点击虚拟机的[编辑]选项,选择[虚拟网络编辑器] 2.选择[VMnet8],然后点击[NAT设置] 3.记录[子网掩码]和[网关IP],后面会用到 4.进入终端, ...

  7. 南邮CTF--SQL注入题

    南邮CTF--SQL注入题 题目:GBK SQL injection 解析: 1.判断注入点:加入单引号发现被反斜杠转移掉了,换一个,看清题目,GBK,接下来利用宽字节进行注入 2.使用'%df' ' ...

  8. Turtle库学习

    Python Turtle (Python绘图工具) 导入库 import turtle as t ps:为了方便调用我们这里给这个模块在本程序内重命名为 t 1. 画布 顾名思义就是用于绘图的区域 ...

  9. 关于linux安装kettle的总结

    一.部署准备 1.1 JDK安装配置 命令行键入“cd /etc”进入etc目录 命令行键入“vi profile”打开profile文件 敲击键盘ctrl+F到文件末尾 在末尾处,即第一个~的地方, ...

  10. post processing in CFD

    post post Table of Contents 1. Post-processing 1.1. Reverse flow 1.1.1. reasons 1.1.2. solutions 1.2 ...