ACM:DAG上的动态规划------嵌套矩形
来源:互联网 发布:c语言 整数奇偶排序 编辑:程序博客网 时间:2024/05/01 05:15
题目:
有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度)。例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中。你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内。
分析:典型的DP题目,把每一个矩形想象成DAG(有向无环图)中的一个点!然后利用DP。。
状态转移方程:d(i) = max{d(j)+1} 其中(i, j)是DAG中的一条边! 其中d(i)表示从节点(矩形)出发的最长路的长度!
(1)输出字典序最小解
#include <iostream>#include <string>using namespace std;const int MAXN = 1000;int n, x[MAXN], y[MAXN], G[MAXN][MAXN], d[MAXN];int dp(int i) {int &ans = d[i];if(ans > 0) return ans; //记忆化搜索,如果d[i]已经计算过,就直接返回!ans = 1;for(int j = 0; j < n; ++j) {if(G[i][j]) ans = max(ans, dp(j)+1); //算法核心语句:如果节点i可以到达节点j,那么从节点i出发的最长路 等于 从节点j的最长路 + 1}return ans; //返回从节点i出发,可以达到的最长路!}void print(int i) { //以字典序的方式来打印答案!cout << i << endl;for(int j = 0; j < n; ++j) {if(G[i][j] && d[i] == d[j] + 1) { //如果找到下一个节点!立马递归调用print()。print(j);break; //不能忘记break,因为找到下一个点后,没必要再继续找了,不然打印出来的就不止一条路径了!}}}int main() {cin >> n;for(int i = 0; i < n; ++i) {cin >> x[i] >> y[i];if(x[i] > y[i]) {int temp = x[i];x[i] = y[i];y[i] = temp;}}memset(G, 0, sizeof(G));for(int i = 0; i < n; ++i) {for(int j = 0; j < n; ++j) {if(x[i] < x[j] && y[i] < y[j]) {G[i][j] = 1;}}}memset(d, -1, sizeof(d));int ans = 0, best = 0; //best记录的是最长路的起点!for(int i = 0; i < n; ++i) {if(ans < dp(i)) {ans = dp(i); //ans记录的是最长路的长度!best = i;}}cout << ans << endl;print(best);cout << endl;return 0;}
(2)如果要打印出所有的最长路的路径,只将break删除是不够的!那样的话,距离相同的点都会全部打印出来!正确的做法是记录路径上的所有点,在递归结束时才一次性输出整条路经。
//输出所有解:#include <iostream>#include <string>using namespace std;const int MAXN = 10000;int x[MAXN], y[MAXN], G[MAXN][MAXN], d[MAXN], n;int dp(int i) {int &ans = d[i];if(ans > 0) return ans;ans = 1;for(int j = 0; j < n; ++j) {if(G[i][j]) {ans = max(ans, dp(j)+1);}}return ans;}int path[MAXN];void print(int cur, int i) {path[cur] = i;if(d[i] == 1) {for(int j = 0; j <= cur; ++j) cout << path[j] << " ";cout << endl;}for(int j = 0; j < n; ++j) {if(G[i][j] && d[i] == d[j] + 1) print(cur+1, j);}}int main() {cin >> n;for(int i = 0; i < n; ++i) {cin >> x[i] >> y[i];if(x[i] > y[i]) {int temp = x[i];y[i] = x[i];x[i] = temp;}}memset(G, 0, sizeof(G));for(int i = 0; i < n; ++i) {for(int j = 0; j < n; ++j) {if(x[i] < x[j] && y[i] < y[j]) G[i][j] = 1;}}memset(d, -1, sizeof(d));int ans = 0;for(int i = 0; i < n; ++i) ans = max(ans, dp(i));cout << ans << endl;for(int i = 0; i < n; ++i) if(ans == dp(i)) print(0, i);cout << endl;return 0;}
0 0
- ACM:DAG上的动态规划------嵌套矩形
- 矩形嵌套-DAG上的动态规划
- DAG上的动态规划--嵌套矩形
- 嵌套矩形 DAG上的动态规划 算法入门经典
- 嵌套矩形——DAG上的动态规划
- 嵌套矩形——DAG上的动态规划
- nyoj16矩形嵌套(DAG上的动态规划)
- nyoj 16 矩形嵌套 (DAG上的动态规划)
- nyoj 16 嵌套矩形(DAG上的动态规划)
- [DAG上的动态规划]NYOJ 矩形嵌套
- NYOJ 16 矩形嵌套(DAG上的动态规划)
- 嵌套模型(DAG上的动态规划
- 动态规划矩形嵌套及DAG上的最短路径。
- nyoj-16 矩形嵌套 (DAG上的动态规划,记忆化搜索)
- 矩形嵌套 ————DAG(有向无环图)上的动态规划
- 紫书p263 嵌套矩形如何输出所有路径(DAG上的动态规划)
- 矩阵嵌套问题(DAG上的动态规划)
- ACM:DAG上的动态规划------硬币问题
- ios真机抓包命令rvictl
- 浅谈HTTP中Get与Post的区别
- JDK 6 目录结构介绍以及JDK中的工具研究
- SQL 日期转换
- MySQL之功能1 --- Percona-Server5.6首发提供日志审计功能
- ACM:DAG上的动态规划------嵌套矩形
- 矩阵求逆的C语言实现
- iOS下的UILocalNotification的使用
- java的几种常用的排序
- 计算器实验
- 有胃病怎么吃最好
- python操作mysql数据库(常用函数)
- android实现记住用户名和密码以及实现自动登录
- uml类图关系