题目大意:

给定一堆点,具有x,y两个值

找到一组最多的序列,保证点由前到后,x严格上升,y严格下降,并把最大的数目和这一组根据点的编号输出来

这里用两种方法来求解:

1.

我们可以一开始就将数组根据x由大到小排个序,由前往后取,保证x严格上升了

只要每次取得过程中找一条x不相等的关于y的最长下降子序列即可,加个回溯,输出所有点

 #include <cstdio>
#include <cstring>
#include <algorithm> using namespace std;
const int N = ;
int dp[N] , fa[N] , rec[N]; struct Node{
int x , y , id;
bool operator<(const Node &m)const{
if(x == m.x) return y < m.y;
return x < m.x;
}
}node[N]; int main()
{
//freopen("a.in" , "r" , stdin);
int k = ;
while(scanf("%d%d" , &node[k].x , &node[k].y) != EOF){
node[k].id = k + ;
k++;
}
//先保证都是以x由小到大排列
sort(node , node+k); memset(dp , , sizeof(dp));
memset(fa , - , sizeof(fa));
dp[] = ;
//x已满足上升,现在处理y使其按下降顺序排列即可,按照最长上升子序列的O(n^2)的方法类似处理即可
for(int i = ; i<k ; i++){
dp[i] = ;
for(int j = ; j<i ; j++){
if(node[j].x != node[i].x && node[i].y < node[j].y){
if(dp[i] < dp[j] + ){
dp[i] = dp[j] + ;
fa[i] = j;
}
}
}
} int maxn = , la;
for(int i = ; i<k ; i++){
if(maxn < dp[i]) maxn = dp[i] , la = i;
} int cnt = ;
rec[cnt++] = la;
while(fa[la] >= ){
rec[cnt++] = fa[la];
la = fa[la];
}
printf("%d\n" , maxn);
for(int i =cnt- ; i>= ; i--)
printf("%d\n" , node[rec[i]].id); return ;
}

2.

我们对所有m1.x<m2.x , m1.y>m2.y的m1和m2间添加一条有向线段

这样我们可以从所有入度为0的点出发,进行bfs,每一条边认为长度为1,入度为0的点认为dp[i] = 1表示到达第i个点最多能有多少个物品

计算最短路径的过程加个回溯这个题目就解决了

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;
const int N = ;
int dp[N] , fa[N] , rec[N] , k , t , first[N];
int in[N] , vis[N];
queue<int> q; struct Node{
int x , y , id;
bool operator<(const Node &m)const{
if(x == m.x) return y < m.y;
return x < m.x;
}
}node[N]; struct Edge{
int y , next;
}e[N*N]; void add_edge(int x, int y)
{
e[k].y = y , e[k].next = first[x];
first[x] = k++;
} void bfs(int s)
{
memset(vis , , sizeof(vis));
q.push(s);
vis[s] = ;
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = ;
for(int i = first[u] ; i!=- ; i = e[i].next){
int v = e[i].y;
if(dp[v] < dp[u] + ){
dp[v] = dp[u] + ;
fa[v] = u;
if(!vis[v]){
vis[v] = ;
q.push(v);
}
}
}
}
} bool ok(int ith1 , int ith2)
{
return node[ith1].x < node[ith2].x && node[ith1].y > node[ith2].y;
} int main()
{
// freopen("a.in" , "r" , stdin);
t = , k = ;
memset(first , - , sizeof(first));
memset(dp , , sizeof(dp));
memset(in , , sizeof(in));
while(scanf("%d%d" , &node[t].x , &node[t].y) != EOF){
node[t].id = t + ;
t++;
} for(int i = ; i<t ; i++){
for(int j = ; j<i ; j++){
if(ok(i , j)){
add_edge(i , j);
in[j] ++;
}
if(ok(j , i)){
add_edge(j , i);
in[i] ++;
}
}
} for(int i = ; i<t ; i++)
if(in[i] == ){
dp[i] = ;
bfs(i);
} int maxn = , la;
for(int i = ; i<t ; i++){
if(maxn < dp[i]){
maxn = max(maxn , dp[i]);
la = i;
}
} int cnt = ;
rec[cnt++] = la;
while(fa[la]){
rec[cnt++] = fa[la];
la = fa[la];
}
printf("%d\n" , maxn);
for(int i = cnt- ; i>= ; i--)
printf("%d\n" , rec[i]); return ;
}

HDU 1160 排序或者通过最短路两种方法解决的更多相关文章

  1. 两种方法解决 "The License CNEKJPQZEX- has been cancelled..." 问题

    今天在使用 2017 的 IDEA 和 Pycharm 等IDE的时候,提示了如题的问题.之前实在 http://idea.lanyus.com/ 网站点击生成注册码,复制粘贴到 IDEA 中就好了, ...

  2. 两种方法解决tomcat的 Failed to initialize end point associated with ProtocolHandler ["http-apr-8080"]

    出现这种原因主要是8080端口被占用了. 解决1: 打开任务管理器看看里面有没有javaw的线程,把它关了再重新启动tomcat看看. 解决2: 修改tomcat /conf /server.xml ...

  3. 解决vue项目eslint校验 Do not use 'new' for side effects 的两种方法

    import Vue from 'vue' import App from './App.vue' import router from './router' new Vue({ el: '#app' ...

  4. 转:python list排序的两种方法及实例讲解

    对List进行排序,Python提供了两个方法 方法1.用List的内建函数list.sort进行排序 list.sort(func=None, key=None, reverse=False) Py ...

  5. 用Java集合中的Collections.sort方法对list排序的两种方法

    用Collections.sort方法对list排序有两种方法第一种是list中的对象实现Comparable接口,如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

  6. python list排序的两种方法及实例讲解

    对List进行排序,Python提供了两个方法方法1 用List的内建函数list sort进行排序list sort(func=None, key=None, reverse=False)Pytho ...

  7. MongoDB实现分页(两种方法)

    1.插入实验数据 偷懒用下samus,100条. ; i < ; i++) { Document doc = new Document(); doc["ID"] = i; d ...

  8. 计算理论:NFA转DFA的两种方法

    本文将以两种方法实现NFA转DFA,并利用C语言实现. 方法二已利用HNU OJ系统验证,方法一迷之WA,但思路应该是对的,自试方案,测试均通过. (主要是思路,AC均浮云,大概又有什么奇怪的Case ...

  9. MySQL中删除数据的两种方法

    转自:http://blog.csdn.net/apache6/article/details/2778878 1. 在MySQL中有两种方法可以删除数据: 一种是delete语句,另一种是trunc ...

随机推荐

  1. bzoj 1026: [SCOI2009]windy数【数位dp】

    忘记limit不能记WA了一发-- 典型数位dp,变成work(r)-work(l-1),然后dfs的时候记录w当前位置,la上一个数选的什么,lm当前位是否有上限,ok当前位是否可以不考虑差大于等于 ...

  2. bzoj 1050: [HAOI2006]旅行comf【枚举+并查集】

    m是5000,就想到了直接枚举比例 具体做法是是先把边按照边权从小到大排序,然后先枚举最小边权,再枚举最大边权,就是从最小边权里一个一个加进并查集里,每次查st是否联通,联通则退出,更新答案 #inc ...

  3. js 本地存储 localStorage 之 angular

    今天项目中用到 php yii框架 用的不是 angular路由 所以用rootScope传值是不行的 我就用到了 localStorage 本地持久化存储 如下 set 顾名思义是设置 值 loca ...

  4. ECMA里面的一元符

    只能操作一个值的叫做一元操作符.一元操作符是ECMAScript中最简单的操作符 1.递增和递减操作符 递增和递减操作符直接借鉴自c,而且各有俩个版本,前置型和后置型.顾名思义,前置型就是位于要操作的 ...

  5. zepto中给不存在的元素设置样式并绑定事件的坑

    在移动端使用zepto选择器时,一般如果元素不存在会返回一个空的zepto对象. zepto在设置元素样式时,提供了两个入参方式,一种键值对方式$(".ter").css({&qu ...

  6. SpringBoot中如何使用jpa和jpa的相关知识总结

    jpa常用的注解: 注解 解释 @Entity 声明类为实体或表. @Table 声明表名. @Basic 指定非约束明确的各个字段. @Embedded 指定类或它的值是一个可嵌入的类的实例的实体的 ...

  7. windows服务器修改远程登录的端口+防火墙配置

    话不多说,一个bat文件,快速修改注册表端口.你只需要做的是另外防火墙添加例外端口后重启即可.经测试2008-2012-2016-2019正常使用! @echo off rem 查找端口号 for / ...

  8. 关于MD5解密网站。www.cmd5.com

    第一次听说这个网站,本人的名字居然也能够被解密,而且还是需要付费取得明文! 大家知道,md5加密是我们常用的加密方式,这个加密方式的好处在于不可逆.而且任何环境下算出的密文应该都是相同的,所以在大家登 ...

  9. linux vim 常用操作

    vim 字符级 上k下j左h右i,键盘的方向键也可以移动 单词级 b上个单词首字母 w下个单词首字母 e下个单词的尾字母 行级 0行首 $行尾 删除 dd 删除光标所在行 文档级 gg 文档首行,首个 ...

  10. MySQL基础:show命令总结

    show命令 show命令可以提供关于数据库.表.列,或关于服务器的状态信息. 总结 # 显示二进制文件以及文件大小(需要开启二进制日志记录功能) SHOW {BINARY | MASTER} LOG ...