[Bzoj3193][JLOI2013]地形生成 (排列组合 + DP)
3193: [JLOI2013]地形生成
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 459 Solved: 223
[Submit][Status][Discuss]
Description
Input
Output
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)的更多相关文章
- [bzoj3193][JLOI2013]地形生成_排列组合_贪心
[JLOI2013]地形生成 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3193 题解: 这种求总排列的题,一种常规做法就是所有的元素 ...
- BZOJ3193 [JLOI2013]地形生成 【dp】
题目链接 BZOJ3193 题解 注意\(key\)是小于 第一问,显然按高度降序排序,逐个插入 如果高度各不相同,那么之前插入的都比当前插入的\(i\)大,可插入的位置个数就确定了 由于存在高度相同 ...
- BZOJ3193: [JLOI2013]地形生成
传送门 Sol 第一问可以考虑按照山的高度从大到小放 但是这样如果遇到高度相同的就不好考虑,那么同时要求数量限制从小到大 这样每次放的时候后面的一定不会影响前面,并且高度相同的时候前面能放的位置后面的 ...
- BZOJ 3193: [JLOI2013]地形生成 计数 + 组合 + 动态规划
第一问: 先不考虑山的高度有相同的:直接按照高度降序排序,试着将每一座山插入到前面山的缝隙中. 当然,这并不代表这些山的相对位置是固定的,因为后面高度更低的山是有机会插入进来的,所以就可以做到将所有情 ...
- 【BZOJ3193】 [JLOI2013]地形生成
BZOJ3193 [JLOI2013]地形生成 Solution 第一问不是很简单吗? 直接计数就好了. 第二问思考无果看了看hyj神仙的代码,发现可以dp求解. 具体可以看代码(其实主要是我说不清楚 ...
- 【BZOJ3193】[JLOI2013]地形生成 DP
[BZOJ3193][JLOI2013]地形生成 Description 最近IK正在做关于地形建模的工作.其中一个工作阶段就是把一些山排列成一行.每座山都有各不相同的标号和高度.为了遵从一些设计上的 ...
- 【BZOJ3193】[JLOI2013]地形生成(动态规划)
[BZOJ3193][JLOI2013]地形生成(动态规划) 题面 BZOJ 洛谷 题解 第一问不难,首先按照山的高度从大往小排序,这样子只需要抉择前面有几座山就好了.然而有高度相同的山.其实也不麻烦 ...
- [JLOI2013]地形生成[组合计数]
题意 \(n\) 元素各有一个高度 \(h\) 和关键数字 \(b\) .求有多少个下标序列和高度序列,满足对任意 \(i\),\(j< i\) 且 \(h_j < h_i\)的 \(j\ ...
- [JLOI2013]地形生成
JLOI2013过了好长时间,才写第四题.. 第一问比较好想. 第二问我想到了n^3次方的做法,但是数据....于是没敢写,然后上网查了一下题解,居然是O(n^3)过的,数据这么弱... /* * P ...
随机推荐
- java语言基础-类型运算细节
代码一: public class varDemo{ public static void main(String[] args) { byte a2; a2=3+4; System.out.prin ...
- qt 设置阴影 不显示黑色边框
this->setAttribute(Qt::WA_TranslucentBackground);
- 洛谷 P2515 [HAOI2010]软件安装
题目描述 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是 ...
- centos7 搭建双网卡bond1(主备模式)实例
前景须知: 在redhat6 中网卡叫bond,在redhat7及centos7中改名team,此处只记录centos7中双网卡主备搭建过程. 应用情景:实现网络的高可用,防止一条网线或交换机故障影响 ...
- PHP03 移动互联网和PHP
学习要点 移动互联网 云计算 网络通信协议 Apache http服务器 PHP运行原理 学习目标 理解网络通信协议 掌握PHP运行原理 WAMP开发环境的搭建 移动互联网 定义 移动互联网,就是 ...
- JavaEE-02 JSP数据交互01
学习要点 request对象 response对象 转发与重定向 session对象 include指令 课程回顾 需求描述:编写JSP页面,计算2000—3000年中存在几个闰年. 实现分析:判断闰 ...
- hdu 6441 Find Integer(费马大定理+勾股数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6441(本题来源于2018年中国大学生程序设计竞赛网络选拔赛) 题意:输入n和a,求满足等式a^n+b^ ...
- Sphinx排序模式
目前SPHINX支持6种排序模式.分别是: 1. SPH_SORT_RELEVANCE2. SPH_SORT_ATTR_DESC3. SPH_SORT_ATTR_ASC4. SPH_SORT_TIME ...
- TCP三次握手简单理解
- c++_加法变乘法
加法变乘法 我们都知道:1+2+3+ ... + 49 = 1225现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015 比如:1+2+3+...+10*11+12+...+27*28+29+ ...