多校8-1003-hdu4372-Count the Building题解
来源:互联网 发布:java输出数组全部元素 编辑:程序博客网 时间:2024/05/16 18:35
Brief Description:
有N个高楼,楼的高度为N的一个排列,现在从左到右能看到x个,从右往左能看到y个,问高楼一共有多少种排列。能看到高楼的前提是后面的高楼没有被前面的高楼挡住(即后面高楼的高度大于前面高楼的高度)
Analysis:
方法一:
摘自题解+修正题解笔误+个人理解:
设dp[i][j][k] 为共i个楼,从左往后看到共j个,从右往左看共k个的方案种数
dp2[i][j] 为共i个楼,从左往右看共j个的方案种数
则dp2[i][j] = sum(dp[i][j][k]) 1<=k<=i
枚举当前最高建筑物的位置,即将排列分为前后两半,分解为两个子问题
dp[i][j][k] = sum( C(i-1,t)*dp2[t][j]*dp2[i-1-t][k] ) (0<=t<=i-1)
其中C(n,m)为组合数
复杂度O(n^4)。要超时。
评注:dp[i][j][k]的状态设计还是很好想的,这个问题也是很好分解为子问题的,通过枚举最高建筑物来分解子问题,这时或许很自然的就引入了dp2[i][j].
方法二:
dp[n][x][y]表示一共n幢楼,从左数看到x幢,从右数看到y幢,则
dp[n][x][y] = dp[n-1][x-1][y]+dp[n-1][x][y-1]+(n-2)*(dp[n-1][x][y])
就是枚举一下最低的楼的位置,最左,最右,和中间。
复杂度 O(n^3) 。要超时。
评注:方法一用的是最高建筑物来分解子问题,方法二用的是最低,似乎更简单了?
方法三:
f[n][k] 表示单边看过去,共 n 幢楼,最高楼在另一端,看到了 k 幢的排列个数。于是
f[n][k] = sigma(f[x][k - 1] * C[n - 2][x - 1] * (n - x - 1)!)
= sigma(f[x][k - 1] * (n - 2)! / (x - 1)!)
= f[n - 1][k] * (n - 2) + f[n - 1][k - 1]
于是算答案就是 answer(n, x, y) = sigma(f[i][x] * f[n - i + 1][y] * C[n - 1][i - 1]) 。 (也是枚举最高建筑物)
预处理 O(n^2),每组 case O(n)。不过还是要超时。
评注:这种DP设计状态的方式也很常见。f[n][k]转为f[n-1][k],f[n-1][k-1]的式子变化需要一点点的小技巧。
方法四:
n^3的算法暴力出后找规律可得dp[n][i][j] = dp[n][i - 1][j + 1] * j / (i - 1)。
其中dp[n][1][i] = S1[n - 1][i - 1]
进一步化简得到dp[n][i][j] = S1[n - 1][i + j - 2] * C[i + j - 2][i - 1]
评注:暂时不是很懂,还是得看一下stirling数和catalan数
总结:这道题让我感受到了组合计数问题的奇妙,让我很想学一下几种常用的组合计数和各种计数的思维方式。+U!
- 多校8-1003-hdu4372-Count the Building题解
- hdu4372 Count the Buildings
- HDU4372 Count the Buildings ---组合数学
- #HDU4372#Count the Buildings(第一类Stirling数经典)
- hdu4372(第一类斯特林数) Count the Buildings
- hdu4372(count buildings)
- hdu4381Count the Building-多校9-1002-题解
- hdu3625 Examining the Rooms && hdu4372 Count the Buildings(第一类斯特林数)
- HDU4372-Count the Buildings(第一类Stirling数+组合计数)
- HDU 4588 Count The Carries 题解
- hdu 3336 Count the string 用心写的题解
- LeetCode题解:Count Primes
- leetcode 题解 Count Primes
- HackerRank Pattern Count 题解
- Lintcode131 Building Outline solution 题解
- Zoj 1610 Count the Colors 详细题解(区间染色,求染色段)
- Building the network
- Building the Data Warehouse
- 王垠:知识分子的傲慢与偏见
- JAVA实现的批量更改文件后缀名的程序
- 检测报销人有无C6账户,有则设列只读。
- BNU OJ The More The Better || HDU 4379
- NSDictionary,NSArray,NSSet
- 多校8-1003-hdu4372-Count the Building题解
- sql
- vs2008编译QT开源项目--太阳神三国杀源码分析(五) 分牌及出牌
- 5.类的扩展之objective-c
- 如何错误处理?
- PHP中$_SERVER的详细用法
- windows如何能在“运行”框输入名称就启动相应的软件
- Arduino Mega_ADK ADC
- SELECT 失败,因为下列 SET 选项的设置不正确: 'ARITHABORT'……