题目大意:

给定一堆点,具有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. 10.16NOIP模拟赛

    /* 我是一个大sb */ #include<iostream> #include<cstdio> #include<cstring> #include<qu ...

  2. Akka源码分析-Cluster-Metrics

    一个应用软件维护的后期一定是要做监控,akka也不例外,它提供了集群模式下的度量扩展插件. 其实如果读者读过前面的系列文章的话,应该是能够自己写一个这样的监控工具的.简单来说就是创建一个actor,它 ...

  3. webservice 权限控制

    webservice 如何限制访问,权限控制?1.服务器端总是要input消息必须携带用户名.密码信息 如果不用cxf框架,SOAP消息(xml片段)的生成.解析都是有程序员负责 2.拦截器 为了让程 ...

  4. ASP.Net 知识点总结(四)

    1.get和post 的区别 get是从服务器上获取数据,post是向服务器传送数据; get安全性非常低,数据显示在地址栏,post安全性较高: 但是执行效率却比Post方法好: get有字节限制为 ...

  5. [笔试面试题] 10-C和C++区别相关

    1 C和C++有什么不同? 机制不同:C是面向过程的(但C也可以编写面向对象的程序):C++是面向对象的,提供了类.但是,C++编写面向对象的程序比C容易. 适用领域不同:C适合要求代码体积小的,效率 ...

  6. 状压DP UVA 10817 Headmaster's Headache

    题目传送门 /* 题意:学校有在任的老师和应聘的老师,选择一些应聘老师,使得每门科目至少两个老师教,问最少花费多少 状压DP:一看到数据那么小,肯定是状压了.这个状态不好想,dp[s1][s2]表示s ...

  7. hdu5122 K.Bro Sorting

    思路: 模拟. 实现: #include <iostream> #include <cstdio> using namespace std; ], n, t; int main ...

  8. (3)左右值再探与decltype

    Decltype 类型指示符 “引用从来都作为其所指对象的同义词出现,只有用在decltype处是一个例外” 理解: Decltype和auto区别: 1.     auto是从表达式类型推断出要定义 ...

  9. Farseer.net轻量级开源框架 中级篇:数据绑定

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 中级篇: DbFactory数据工厂 下一篇:Farseer.net轻量级开源框架 中级篇: ...

  10. NVIDIA各个领域芯片现阶段的性能和适应范围

    NVIDIA作为老牌显卡厂商,在AI领域深耕多年.功夫不负有心人,一朝AI火,NVIDIA大爆发,NVIDIA每年送给科研院所和高校的大量显卡,大力推广Physix和CUDA,终于钓了产业的大鱼. 由 ...