P3255 [JLOI2013] 地性生成 题解
update on 2025.3.9:改了毒瘤马蜂
题面大意
给你
题解
一个较为经典的 trick,容易发现对于任意一座山,比他矮的放哪和他的方案没有关系,于是我们先按高度递减为第一关键字,关键字递增为第二关键字来排序(为什么要设置第二关键字小问中会说)。
第一问
排完序后枚举每一座山,注意到因为设置了第二关键字,所以限制比较紧的山会先插入,那么这座山一定可以插在高度一样的山后面,因为高度都一样,他们的限制还比我紧,我跟着他们插肯定是合法的。
然后注意到假设比这座山更高的山有
于是第
第二问
稍微难了一点,我们设
如果到了新高度就清空,初值是
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=2011;
struct nb{
int gao,jian;
}a[1010];
int n,dp[1010][1010],sum[1010],ans;
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].gao>>a[i].jian;
a[i].jian--;
}
sort(a+1,a+1+n,[](nb x,nb y){
if(x.gao!=y.gao){
return x.gao>y.gao;
}
return x.jian<y.jian;
});
ans=1;
int tot=0;
for(int i=1;i<=n;i++){
while(a[tot+1].gao>a[i].gao){
tot++;
}
ans=ans*(min(a[i].jian,tot)+i-tot)%mod;
}
cout<<ans<<' ';
tot=0,ans=1;
dp[0][1]=1;
for(int i=1;i<=n;i++){
while(a[tot+1].gao>a[i].gao){
tot++;
}
for(int j=1;j<=n+1;j++){
sum[j]=(sum[j-1]+dp[i-1][j])%mod;
}
if(tot==i-1){
ans=ans*sum[n+1]%mod;
for(int j=1;j<=n+1;j++){
sum[j]=1;
}
}
for(int j=1;j<=min(tot,a[i].jian)+1;j++){
dp[i][j]=sum[j];
}
}
for(int j=1;j<=n+1;j++){
sum[j]=(sum[j-1]+dp[n][j])%mod;
}
cout<<ans*sum[n+1]%mod;
return 0;
}
本文作者:LEWISAK
本文链接:https://www.cnblogs.com/lewisak/p/18751447
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步