UVALive 6486 Skyscrapers 简单动态规划
题意:
有N个格子排成一排,在每个格子里填上1到N的数(每个只能填一次),分别代表每个格子的高度。现在给你两个数left和right,分别表示从左往右看,和从右往左看,能看到的格子数。问有多少种情况。
数据范围: N<5000;
思路:
首先枚举最高的一块,在最高的格子的后面的格子都一定会被挡住。所以,除了最高的那一格之外,从左边能看到的格子,从右边一定看不到;从右边能看到的也是一样。
因此,除了最高的那个格子,左边的是否能被看见,和右边的无关。所以,我们可以以最高的格子为界,把这一排格子分成左右两部分。
在这样子,我们就可以把左边和右边看成是一种情况:把n个高度不等的方块排成一列,要求从前面只能看到k个,有多少种。
我们把上面问题(n个格子,看见k个)的结果记为f[n, k]。
对于上面那个问题,我们考虑两种情况:最高的放在最后,和最高的不放在最后。
1. 如果最高的放最后,因为最高的一定不会被挡住,所以,前面n-1个格子,需要被看见k-1个。
2. 如果最高的不放在最后,那么,最后一格一定会被挡住(因为最高的在它前面,而且会挡住他),所以前面n-1个格子,仍然需要被看见k个。
上面第一种,情况只有一种;而第二种情况有n-1种(把n-1个不是最高的中任意一个放到最后都满足)。
所以 f[n, k] = f[n-1, k-1] + (n-1)*f[n-1, k]。
另外就是边界情况,k=1的时候,这样一定就是最高的放最前面,后面随便放,所以就是 f[n, 1] = (n-1)!。
还有就是,组合数可以用杨辉三角来求,这个是学弟说的,本人数学功底太差 0 0、
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; typedef long long ll;
const int MAXN = ;
const ll MOD = (ll)1e9+7.0; ll dp[MAXN][MAXN];
ll C[MAXN][MAXN];
ll ni[MAXN]; int n, l, r;
ll ans; int main()
{
#ifdef Phantom01
freopen("in.txt", "r", stdin);
freopen("my.out", "w", stdout);
#endif // Phantom01 dp[][] = dp[][] = ;
for (int i = ; i < MAXN; i++)
dp[][i] = dp[i][] = ;
for (int i = ; i < MAXN; i++)
dp[i][] = (dp[i-][]*(i-))%MOD;
for (int i = ; i < MAXN; i++)
for (int j = ; j < MAXN; j++)
dp[i][j] = (dp[i-][j-]+(dp[i-][j]*(i-))%MOD)%MOD; for (int i = ; i < MAXN; i++) {
C[i][] = ;
for (int j = ; j <= i; j++)
C[i][j] = (C[i-][j]+C[i-][j-])%MOD;
} while (scanf("%d%d%d", &n, &l, &r)!=EOF) {
if (!(n||l||r)) break;
ans = ;
if ((l+r)<=(n+)) {
for (int i = l; i <= (n-r+); i++) {
ans = (ans+( ( (dp[i-][l-]*dp[n-i][r-])%MOD) *C[n-][i-])%MOD)%MOD;
}
}
printf("%d\n", (int)ans);
}
return ;
}
UVALive 6486 Skyscrapers 简单动态规划的更多相关文章
- 简单动态规划——三逆数的O(N^2)解法!
[算法]简单动态规划——三逆数的O(N^2)解法! 问题描述: 三逆数定义:给一个数的序列A[0,1,....N-1]),当i<j<k且A[i]>A[j]>A[k]时,称作ai ...
- 简单动态规划-LeetCode198
题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...
- POJ 1163 The Triangle(简单动态规划)
http://poj.org/problem?id=1163 The Triangle Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
- 【算法】简单动态规划——三逆数的O(N^2)解法!
问题描述: 三逆数定义:给一个数的序列A[0,1,....N-1]),当i<j<k且A[i]>A[j]>A[k]时,称作ai,aj,ak为一个三逆数. 现在给定一个长度为N的数 ...
- 51nod 1270 数组的最大代价 思路:简单动态规划
这题是看起来很复杂,但是换个思路就简单了的题目. 首先每个点要么取b[i],要么取1,因为取中间值毫无意义,不能增加最大代价S. 用一个二维数组做动态规划就很简单了. dp[i][0]表示第i个点取1 ...
- HDU 1176 免费馅饼 简单动态规划
世道很简单的动态规划,但是却错了,让我很无语,改来改去还是不对,第二天有写就对了,之后我就耐着性子慢慢比较之前的错误代码,发现 第一次错:纯粹用了a[i][j]+=max3(a[i+1][j-1], ...
- HDUOJ----2571(命运)(简单动态规划)
命运 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...
- 338. Counting Bits_比特位计数_简单动态规划
https://leetcode.com/problems/counting-bits/ 这是初步了解动态规划后做的第一道题,体验还不错... 看完题目要求后,写出前10个数的二进制数,发现了以下规律 ...
- hdu1176--免费馅饼(简单动态规划)
都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内.馅饼如果掉在了地上当然就 ...
随机推荐
- Android 优雅的让Fragment监听返回键
Activity可以很容易的得到物理返回键的监听事件,而Fragment却不能.假设FragmentActivity有三个Fragment,一般安卓用户期望点击返回键会一层层返回到FragmentAc ...
- Codeforces 987B. High School: Become Human
解题思路: 1.题意:判断x^y和y^x谁大谁小. 2.由于x^y和y^x太大了,时间复杂度也不允许,所以做同等变换,比较e^(ylnx)和e^(xlny). 3.即为比较ylnx和xlny的大小. ...
- 转义JavaScript特殊字符
JavaScriptUtils.javaScriptEscape("%admin' or '1=1") //转义JavaScript特殊字符
- PyQuery使用
PyQuery库是一个非常强大的网页解析库,如果你有前端开发经验的,都应该接触过jQuery,那么PyQuery就是你非常绝佳的选择,PyQuery 是 Python 仿照 jQuery 的严格实现. ...
- Vue 基础篇
Vue 基础篇 一.框架与库的区别 JQ库->DOM(DOM操作) + Ajax请求 art-template库->模板引擎 框架 -> 全方位.功能齐全 简易的DOM体验 + 发请 ...
- Django综合基础知识
Django框架简介 MVC框架和MTV框架 MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View) ...
- C语言运行时数据结构
段(Segment): 对象文件/可执行文件: SVr4 UNIX上被称为ELF(起初"Extensible Linker Format", 现在"Executable ...
- Python学习————字典的增删改查
增加:dic1['KEY'] = value -->若之前有KEY,则会覆盖.若没有KEY,则新增至尾处dic.setdefault('KEY',value/None) --->若之前有K ...
- Hadoop的datanode超时时间设置
datanode进程死亡或者网络故障造成datanode无法与namenode通信, namenode不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长. HDFS默认的超时时长为10 ...
- 洛谷——P2615 神奇的幻方 【Noip2015 day1t1】
https://www.luogu.org/problem/show?pid=2615 题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之 ...