DAG模型——嵌套矩阵
有向无环图上的动态规划是学习动态规划的基础,很多问题都可以转化为DAG上的最长路、最短路或路径计数问题。
嵌套矩阵
有n个矩阵,每个矩阵可以用两个整数a,b描述,表示它的长和宽。矩阵X(a,b)可以嵌套在矩阵Y(c,d)中当且仅当a<c,b<d,或者b<c,a<d(相当于把矩阵X旋转90。)例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)内。你的任务是选出尽量多的矩阵排成一行,使得除了最后一个只之外,每一个矩形都可以嵌套在下一个矩形内。
分析:
矩阵之间的“可嵌套”关系是一个典型的二元关系,二元关系可以用图来建模。如果矩形X可以嵌套在矩形Y里,我们就从X到Y连一条有向边,这个图是无环的,因为一个矩形无法直接或者间接地嵌套在自己内部。换句话说,它是一个DAG,我们的任务便是求DAG上的最长路径。
设d(i)表示从结点i 出发的最长路长度。第一步只能到它的相邻点,d(i) = max{d(j)+1|(i,j)属于E},其中E是边集。最终答案是所有d(i)中的最大值。假设用邻接矩阵保存在矩阵G中。
记忆化搜索代码如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define maxn 1000
using namespace std;
int G[maxn][maxn], a[maxn], b[maxn], d[maxn], n, answer;
int dp(int i)
{
int& ans = d[i];
if (ans > ) return ans;
ans = ;
for(int j = ; j <= n; ++j) if(G[i][j]) ans = max(ans, dp(j)+);
return ans;
}
void print_ans(int i)
{
printf("%d(%d, %d) ", i, a[i], b[i]);
for(int j = ; j <= n; ++j) if(G[i][j] && d[j]+ == d[i])
{
print_ans(j);
break;
}
} int path[maxn] = {}, cnt = ;
void print_all(int i)
{
//输出所有符合条件的路径
path[++cnt] = i;
if(cnt == answer)
{
for(int j = ; j <= cnt; ++j) printf("%d(%d, %d) ", path[j], a[path[j]], b[path[j]]);
printf("\n");
}
else for(int j = ; j <= n; ++j) if(G[i][j] && d[j]+ == d[i])
{
print_all(j);
}
--cnt;
}
/*
//作者的方法
int path[maxn];
void print_all(int cur, int i) {
path[cur] = i;
if(d[i] == 1) {
for(int j = 0; j <= cur; j++) printf("%d ", path[j]);
printf("\n");
}
for(int j = 1; j <= n; j++) if(G[i][j] && d[i] == d[j]+1)
print_all(cur+1, j);
}
*/
int main()
{
freopen("9-2.in", "r", stdin);
scanf("%d", &n);
for(int i = ; i <= n; ++i) scanf("%d%d", a+i, b+i);
memset(G, , sizeof(G));
for(int i = ; i <= n; ++i)
for(int j = ; j <= n; ++j) if((a[i]>a[j]&&b[i]>b[j])||(a[i]>b[j]&&b[i]>a[j]))
G[i][j] = ;
int t, s;
answer = -;
memset(d, , sizeof(d));
for (int i = ; i <= n; ++i)
{
t = dp(i);
if(answer < t)
{
answer = t;
s = i;
}
}
printf("%d\n", answer);
print_ans(s);
printf("\nAll routes:\n");
//print_all(0, s);
print_all(s);
return ;
}
另一代码如下:
//另附0ms 236kb的DP思路:按边长降序排序,用类似LIS的方法求解,只是比较元素大小的方法变成了比较长和宽
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define maxn 1008
using namespace std;
int G[maxn][maxn], a[maxn], b[maxn], d[maxn], n;
int dp(int i)
{
int& ans = d[i];
if (ans > ) return ans;
ans = ;
for(int j = ; j <= n; ++j) if(G[i][j]) ans = max(ans, dp(j)+);
return ans;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(int i = ; i <= n; ++i) scanf("%d%d", a+i, b+i);
memset(G, , sizeof(G));
for(int i = ; i <= n; ++i)
for(int j = ; j <= n; ++j) if((a[i]>a[j]&&b[i]>b[j])||(a[i]>b[j]&&b[i]>a[j]))
G[i][j] = ;
int ans = -, t, s;
memset(d, , sizeof(d));
for (int i = ; i <= n; ++i)
{
t = dp(i);
if(ans < t)
{
ans = t;
s = i;
}
}
printf("%d\n", ans);
}
return ;
}
DAG模型——嵌套矩阵的更多相关文章
- NYOJ16|嵌套矩形|DP|DAG模型|记忆化搜索
矩形嵌套 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a& ...
- UVA103 dp基础题,DAG模型
1.UVA103 嵌套n维空间 DAG模型记忆化搜索,或者 最长上升子序列. 2.dp[i]=max( dp[j]+1),(第i个小于第j个) (1) //DAG模型记忆化搜索 #include< ...
- WEBGL学习【四】模型视图矩阵
<html lang="zh-CN"> <!--服务器运行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWe ...
- OpenGL(五) 三维变换之模型视图矩阵
计算机三维图形学中,一个基本的任务是如何描述三维空间中一个物体位置的变化,也就是如何 描述物体的运动.通常情况下,物体位置的变化包含三个基本的变化:平移.旋转和缩放,物体的运动也可以用这三个基本的运动 ...
- HDU 1588 矩阵快速幂 嵌套矩阵
这个题目搞了我差不多一个下午,之前自己推出一个公式,即 f[n+k]=k*f[n]+f[n-1]结果发现根本不能用,无法降低复杂度. 后来又个博客的做法相当叼,就按他的做法来了 即 最终求得是 S(n ...
- DAG上的动态规划——嵌套矩阵问题
问题描述:有n个矩形,每个矩形可以用两个整数a,b描述,表示它的长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d,或者b<c,a<d(相当于把矩形X旋 ...
- DAG模型(矩形嵌套)
推荐在线例题:http://acm.nyist.net/JudgeOnline/problem.php?pid=16 题摘: 矩形嵌套 时间限制:3000 ms | 内存限制:65535 KB 难 ...
- DAG模型
数字三角形: 1.递归计算 int solve(int i,int j) { :max(solve(i+,j),solve(i+,j+))); } 2.记忆化搜索,不用指明计算顺序,并且保证每个状态只 ...
- DAG 模型 stacking boxes 动态规划
题目:UVA 103 stacking boxes 题目大意: 给你两个数,一个是盒子的个数,一个是每一个盒子的维数.将一个个盒子互相装起来,让你求最多可以装多少个,要求字典序最小. 解析:这个就是盒 ...
随机推荐
- Scala学习笔记(三)类层级和特质
无参方法 功能:将方法的定义转换为属性字段的定义: 作用范围:方法中没有参数,并且方法仅能通过读取所包含的对象属性去访问可变状态,而不改变可变状态,就可使用无参方法: 例子: abstract cla ...
- Linux内核系列设备模型(一) Kobject与Kset
1.Kobject Kobject是设备驱动模型的核心结构,它使所有设备在底层都有统一的接口.在内核注册的kobject对象都会对应sysfs文件系统中的一个目录(目录名称有Kobject结构中k_n ...
- HW4.4
public class Solution { public static void main(String[] args) { final double KILOMETERS_PER_MILE = ...
- BCP的用法
bcp kaiser..kp_rates in c:\kp.bcp -U buykporg -P buykporg -S localhost -c bcp ccrm_oem_shqc.."s ...
- poj 2325 Persistent Numbers (贪心+高精度)
把输入数字每次从9-2除,能整除则记录该数字,最后从小到大输出. 应该算是水题,不过窝第一次写高精度除法,虽然1A,不过中间改了好多次. /****************************** ...
- 数值类对象:NSNumber,NSValue,NSNull
基本,集合,复杂,对象 可用对象封装基本数值,然后将对象放入NSArray或NSDictionary 中. 用对象封装基本数值后,即可给其发送消息. 数值类型包括:NSNumber,NSValue,N ...
- Win+R指令(2)
1. gpedit.msc-----组策略 2. sndrec32-------录音机 3. Nslookup-------IP地址侦测器 ,是一个 监测网络中 DNS 服务器是否能正确实现域名解析的 ...
- Filter过滤器(1)
Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 ht ...
- windows批量创建用户
一.建立用户的命令行语法: 建立用户:net user 用户名 密码 /add (如:net user test 123 /add) 提升权限:net localgro ...
- <Android>从窗口泄漏谈android:configChanges属性
今天有幸去哥们的大公司做了半天的暂时工,一个偶现的Bug折腾了他好久,好不easy今天抓到了异常Log日志.大致的意思就是android.view.windowleaked--窗口泄漏.我在网上查了资 ...