BZOJ 3193 JLOI2013 地形生成 组合数学

题目大意:给定一些山,每座山有一个高度和一个关键值,现在要将这些山排成一个序列,要求每座山之前高度高于它的山的数量不能超过它的关键值,求合法的标号序列数和高度序列数

= =

首先我们考虑第一问

我们发现高度较小的山对高度较大的山是没有影响的

那么我们可以将山按照高度从大到小排序 每座山插入时都有一些备选位置

将备选位置数相乘即是答案

现在考虑第二问

嘲讽:谁能告诉我O(n^3)到底怎么做= =

我们按照之前的思路将山按照高度从大到小排序

将高度相同的山拎出来 每一座山都有一些位置可选

那么我们不妨在排序的时候将关键值大小作为第二键值进行排序

由于同样高度的山对答案的贡献等价,那么我们不妨让关键值较小的山排在关键值较大的前面

这样得到的方案相当于一个手枪型的点阵从左下角走到右上角的方案数

每次DP一下 是O(n^2)的

虽然数据范围是1000但是由于吉林省选一贯的尿性(数据范围从来不对) O(n^3)也是能过的

只不过作为一个精神强迫症来说卡数据是不对的233

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1010
#define MOD 2011
using namespace std;
struct abcd{
	int height,key;
	bool operator < (const abcd &x) const
	{
		if( height != x.height )
			return height > x.height;
		return key < x.key;
	}
}a[M];
int n,ans1=1,ans2=1;
int main()
{
	int i,j,k;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		scanf("%d%d",&a[i].height,&a[i].key);
		a[i].key--;
	}
	sort(a+1,a+n+1);
	for(i=1;i<=n;i=j)
	{
		static int f[M];
		memset(f,0,sizeof f);
		f[0]=1;
		for(j=i;j<=n&&a[i].height==a[j].height;j++)
		{
			(ans1*=min(i-1,a[j].key)+j-i+1)%=MOD;
			for(k=1;k<=i-1&&k<=a[j].key;k++)
				(f[k]+=f[k-1])%=MOD;
		}
		int temp=0;
		for(k=0;k<=i-1&&k<=a[j-1].key;k++)
			(temp+=f[k])%=MOD;
		(ans2*=temp)%=MOD;
	}
	cout<<ans1<<' '<<ans2<<endl;
	return 0;
}
时间: 2024-10-16 00:33:55

BZOJ 3193 JLOI2013 地形生成 组合数学的相关文章

[JLOI2013]地形生成

题目描述 最近IK正在做关于地形建模的工作.其中一个工作阶段就是把一些山排列成一行.每座山都有各不相同的标号和高度.为了遵从一些设计上的要求,每座山都设置了一个关键数字,要求对于每座山,比它高且排列在它前面的其它山的数目必须少于它的关键数字. 显然满足要求的排列会有很多个. 对于每一个可能的排列,IK生成一个对应的标号序列和等高线序列.标号序列就是按顺序写下每座山的标号. 等高线序列就是按顺序写下它们的高度.例如有两座山,这两座山的一个合法排列的第一座山的标号和高度为1和3,而第二座山的标号和高

luoguP3255 [JLOI2013]地形生成 动态规划

出题人语文真好... 各不相同的标号和高度 = 各不相同的标号 + 单独的高度... 第一问比较简单,考虑从大到小插入,在相同情况下,按关键值从小到大插入 这样子,关键大的元素一定会影响到关键小的元素,不会漏统计 插入$i$号元素时,不妨设比它大的数为$S$个,限制为$lim$,和它相同的且已经插入的数有$j$种 那么有$min(S, lim) + j$种插入的方案 第二问也比较简单 考虑$dp$,令$f(i, j)$表示在相同的数中,插入到了$i$,并且$i$插入在第$j$段 由于插入的顺序是

Day3:关于地形生成

---恢复内容开始--- 今天桃子好像还是没什么动静,不过媳妇倒是有一点见红~ 希望这是马上要出来的前兆了~ 桃子都已经晃点我俩好多回了~ 已经都快习惯来她这个狼来了的征兆了~ -------------------------------任性的分割线--------------------------------- 因为想做一个类似<Minecraft>的游戏,所以各种找关于地形生成的算法~ 虽然之前弄得那个柏林噪音的算法可以,但是欠缺太多东西了~ 不知道是不是我太钻牛角尖了~ 对应该如何制

BZOJ 1005 明明的烦恼 (组合数学)

题解:n为树的节点数,d[ ]为各节点的度数,m为无限制度数的节点数. 则             所以要求在n-2大小的数组中插入tot各序号,共有种插法: 在tot各序号排列中,插第一个节点的方法有种插法: 插第二个节点的方法有种插法: ......... 另外还有m各节点无度数限制,所以它们可任意排列在剩余的n-2-tot的空间中,排列方法总数为 根据乘法原理: #include <cstdio> #include <cmath> int n,m,tot,i,j,d,down

三维地形生成

三维地形生成的相关代码matlab 1 function terrain() 2 n=9;%递归次数 3 H=2;%设置初始正方形四顶点值 4 t=0.2;%控制地貌形态 5 delta=0.01;%初始随机位移偏移量,控制地貌形态 6 size=2^n+1; 7 S=zeros(size,size);%设置size*size的初始方阵 8 S(1,1)=H+sqrt(1-2^(2*t-2))*normrnd(0,1)*delta;%赋初始高度值 9 S(1,size)=H+sqrt(1-2^(

BZOJ 3193 地形生成

这种dp好烦啊. 懒得写题解. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 1050 #define mod 2011 using namespace std; int n,x,y,f[maxn],ans1=1,ans2=1,l[maxn],r[maxn],cnt=0; struct status { int h,f; frien

bzoj 3192: [JLOI2013]删除物品

3192: [JLOI2013]删除物品 Description 箱子再分配问题需要解决如下问题: (1)一共有N个物品,堆成M堆. (2)所有物品都是一样的,但是它们有不同的优先级. (3)你只能够移动某堆中位于顶端的物品. (4)你可以把任意一堆中位于顶端的物品移动到其它某堆的顶端.若此物品是当前所有物品中优先级最高的,可以直接将之删除而不用移动. (5)求出将所有物品删除所需的最小步数.删除操作不计入步数之中. (6)只是一个比较难解决的问题,这里你只需要解决一个比较简单的版本: 不会有两

【BZOJ 3997】 3997: [TJOI2015]组合数学 (DP| 最小链覆盖=最大点独立集)

3997: [TJOI2015]组合数学 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 919  Solved: 664 Description 给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走.问至少走多少次才能将财宝捡完.此对此问题变形,假设每个格子中有好多财宝,而每一次经过一个格子至多只能捡走一块财宝,至少走多少次才能把财宝全部捡完. Input 第一行为正整数T,代表数据组数. 每组数据第一行为正整数N,M代表网格图有

BZOJ 3505 CQOI2014 数三角形 组合数学

题目大意: 给定一个m*n的方格.求上面有多少个格点三角形 m,n<=1000 枚举O(m^3*n^3).铁定超时 我们选择补集法 首先我们随意选择三个不反复的点构成三角形 用组合数算出这一值 然后刨除三点一线的点就可以 枚举三点之中在两边的点的横纵坐标之差,中间点的位置数为GCD(x,y)-1,统计答案就可以 注意初始计算组合数时可能会爆int #include<cstdio> #include<cstring> #include<iostream> #incl