博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【UVA1638】杆子的排列
阅读量:5068 次
发布时间:2019-06-12

本文共 1043 字,大约阅读时间需要 3 分钟。

题面

有高为 1, 2, …, n 的 n 根杆子排成一排, 从左向右能看到 L 根, 从右向左能看到 R 根。求有多少种可能的排列方式。

分析

数据范围仅200,本来是往组合数学方面想的,看到了这个200就放弃了念头,果然是dp

定义dp[i][j][k]是用了高度为1~i的杆子,从左边能看到j个,从右边能看到k个

如果从1转移到n很困难,因为放一个高的杆子进去会造成很多的遮挡影响,是几乎不能维护的。于是考虑从n转移到1,即先放比较高的杆子

加上放好了2~n高度的杆子,再放高度为1的杆子仅有三种情况

1.放在最左边。仅仅是从左看能多看到一个 dp[i][j][k]+=dp[i-1][j-1][k]

2.放在最右边,同理

3.放在中间,一定会被挡住。i-1根杆子间有(i-2)个可以放置的空格,则dp[i][j][k]+=dp[i-1][j][k]*(i-2)。

其实这里i的定义已经发生了一点变化,但是状态转移是很容易理解的

为什么可以把i等效定义为i个,而不是1~i呢?其实这只需要代表是i根高度不同的杆子,2~i的杆子全部砍1,相对高度没有变,也就等效成了1~i-1的杆子

代码

#include
using namespace std;#define mod 998244353#define ll long long#define N 220ll dp[N][N][N];ll t,n,l,r;int main(){ dp[1][1][1]=1; for(ll i=2;i<=200;i++) for(ll j=1;j<=i;j++) for(ll k=1;k<=i-j+1;k++) dp[i][j][k]=(dp[i-1][j-1][k]+dp[i-1][j][k-1]+dp[i-1][j][k]*(i-2)%mod)%mod; scanf("%lld",&t); while(t--) { scanf("%lld%lld%lld",&n,&l,&r); printf("%lld\n",dp[n][l][r]); } return 0;}

 

转载于:https://www.cnblogs.com/NSD-email0820/p/9561589.html

你可能感兴趣的文章
Scaling Pinterest - From 0 To 10s Of Billions Of Page Views A Month In Two Years
查看>>
SelectSort 选择排序
查看>>
关于android 加载https网页的问题
查看>>
BZOJ 1047 HAOI2007 理想的正方形 单调队列
查看>>
C++算法之 一句话推断一个整数是不是2 的整数次方
查看>>
各种语言推断是否是手机设备
查看>>
UVA 11214 Guarding the Chessboard 守卫棋盘(迭代加深+剪枝)
查看>>
POJ - 3685 Matrix
查看>>
jdk1,8 HashMap
查看>>
live555源码研究(五)------DynamicRTSPServer类
查看>>
Java编程思想(八、多态)
查看>>
批量删除前端参数传递及后台接收
查看>>
marquee标签
查看>>
滤波器的频域理解
查看>>
这个看起来有点简单!--------实验吧
查看>>
JavaScript面向对象
查看>>
ubuntu下安装程序的五种方法
查看>>
iframe 子页面获取父页面的元素并且控制样式
查看>>
小知识:js如何更改css样式
查看>>
PHP count down
查看>>