• 【训练题】DAG中的最长路 P1659


    Description

    有n个矩形(编号为1~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)中。你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内。


    Input

    第1行是一个正正数n,表示该组测试数据中含有矩形的个数。接着输入a,b。


    Output

    第1行输出一个整数,表示最长嵌套矩形序列包含的矩形数目。第2行输出最长嵌套矩形序列从左到右的矩形编号,如果有多解,输出字典序最小的。第3行输出一个整数,表示最长嵌套矩形序列的方案数,这个数可能很大,需要输出mod10^9+7的结果。


    Hint

    n<=1000。


    Solution

    首先toposort的方式是错的,,因为dp数组的定义是以这个点为结尾的最长长度,也有可能存在这个点是叶子结点,但因为字典序最小选到它了就不对了。


    然后所以正解应该是dfs记忆化搜索,第一问是记录长度(从汇聚点n+2开始一次伸展到原点0),第三问也是这个原理。


    注意事项:
    1.vis,不写要超时。
    2.dfs的情况因为多了原点0和汇聚点n+2所以要减。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define maxn 500005
    using namespace std;
    struct Edge{
    	int u;
    	int v;
    	int next;
    }edge[maxn];
    int first[maxn],last[maxn],leftt[maxn],rightt[maxn],f[maxn],r[maxn];
    int node,n;
    bool vis[maxn],Vis[maxn];
    void addedge(int u,int v){
    	edge[++node]=(Edge){u,v,0};
    	if(first[u]==0)first[u]=node;
    	else edge[last[u]].next=node;
    	last[u]=node;
    }
    void init(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d%d",&leftt[i],&rightt[i]);
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			if(i==j)continue;
    			if((leftt[i]<leftt[j]&&rightt[i]<rightt[j])||(leftt[i]<rightt[j]&&rightt[i]<leftt[j])){
    				addedge(i,j);
    			}
    		}
    	}
    	for(int i=1;i<=n;i++){
    		addedge(0,i);
    		addedge(i,n+2);
    	}
    }
    int dfs(int s){
    	if(vis[s])return f[s];
    	if(!first[s])return f[s]=1;
    	vis[s]=true;
    	for(int i=first[s];i;i=edge[i].next){
    		int j=edge[i].v;
    		f[s]=max(f[s],dfs(j)+1);
    	}
    	return f[s];
    }
    void outputt(int s){
    	if(s!=0){
    		printf("%d ",s);
    	}
    	int goo=n+2;
    	for(int i=first[s];i;i=edge[i].next){
    		int j=edge[i].v;
    		if(f[j]==f[s]-1)goo=min(goo,j);
    	}
    	if(goo!=n+2)outputt(goo);
    }
    int dfs2(int s){
    	if(!first[s])return r[s]=1;
    	if(Vis[s])return r[s];
    	Vis[s]=1;
    	for(int i=first[s];i;i=edge[i].next){
    		int j=edge[i].v;
    		if(f[j]==f[s]-1)r[s]+=dfs2(j),r[s]%=1000000007;
    	}
    	return r[s];
    }
    int main(){
    	init();
    	printf("%d
    ",dfs(0)-2);
    	outputt(0);
    	printf("
    %d
    ",dfs2(0));
    	return 0;
    }
    
  • 相关阅读:
    图像特征工程
    神经网络在多分类上的应用——数据预处理
    Robotics Lab3 ——图像特征匹配、跟踪与相机运动估计
    Robotics Lab2——相机模型,点云图拼接与深度测量
    Robotics Lab1 —— 基于颜色特征的目标识别与追踪实验
    【Ubuntu16.04】解决Qt安装包(.run文件)不能用./命令执行的问题
    【ROS系统】创建消息(msg)后使用rosmsg命令报错的解决办法
    【ROS系统】执行roslaunch命令启动launch文件提示Invalid roslaunch XML syntax错误的解决办法
    【ROS系统】解决找不到用户工作空间下的程序包的问题——E:No such package
    【UEFI+GPT/BIOS+MBR】两种模式在Windows系统下安装Ubuntu系统
  • 原文地址:https://www.cnblogs.com/virtual-north-Illya/p/10045364.html
Copyright © 2020-2023  润新知