[NOI2019] 机器人

题面

题面描述

得分情况

100pts: 10
95pts: 一些
75/80/85pts: 几个
60pts: 一些
50pts: 很多
45pts: 少量
35pts: 不少
20pts: 暴多
10pts: 一堆
0pts: 巨多
(上述数据及描述性语言来自NOI讲题人的ppt)

题解

20pts: n , B i ≤ 7 n,B_i\leq 7 n,Bi7

B i B_i Bi n n n都非常小,暴力模拟即可

35pts: B i ≤ 100 B_i\leq 100 Bi100

假设一个全局最高点 p p p,钦定 [ 1 , p − 1 ] [1,p-1] [1,p1]内任意点高度小于等于 p p p的高度, [ p + 1 , n ] [p+1,n] [p+1,n]内任意点的高度小于 p p p的高度,显然, p p p [ 1 , n ] [1,n] [1,n]分割为 [ 1 , p − 1 ] [1,p-1] [1,p1] [ p + 1 , n ] [p+1,n] [p+1,n]两个子问题。由此可以区间DP。
d p l , r , x dp_{l,r,x} dpl,r,x表示 [ l , r ] [l,r] [l,r]最大值恰好为x时的方案数,暴力枚举断点和最大值转移,容易得到:
d p l , r , x = ∑ m i d ∑ k ≤ x d p l , m i d − 1 , k ∑ k < x d p m i d + 1 , r , k dp_{l,r,x}=\sum_{mid}\sum_{k\leq x}dp_{l,mid-1,k}\sum_{k<x} dp_{mid+1,r,k} dpl,r,x=midkxdpl,mid1,kk<xdpmid+1,r,k

利用前缀和优化

参考代码:

#include<bits/stdc++.h>
#define ll long long
#define uit unsigned int 
using namespace std;
const int N=301;
const ll M=1e9+7;
int n,A[N],B[N],dp[N][N][110];
int main(){
   
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	int MAX=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&A[i],&B[i]),MAX=max(MAX,B[i]);
	for(int i=1;i<=n;i++){
   
		for(int j=1;j<=MAX;j++){
   
			if(j>=A[i]&&j<=B[i]) dp[i][i][j]++;
			dp[i][i][j]=(dp[i][i][j]+dp[i][i][j-1])%M;
		}
	}
	for(int len=2;len<=n;len++)
		for(int i=1;i+len-1<=n;i++){
   
			int j=i+len-1;
			for(int k=i;k<=j;k++)
				if(abs((k-i)-(j-k))<=2)
				for(int w=A[k];w<=B[k];w++){
   
					if(k==i) dp[i][j][w]=(dp[i][j][w]+dp[k+1][j][w-1])%M;
					else if(k==j) dp[i][j][w]=(dp[i][j][w]+dp[i][k-1][w])%M;
					else dp[i][j][w]=(dp[i][j][w]+1ll*dp[i][k-1][w]*dp[k+1][j][w-1]%M
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值