HDU 1160 排序或者通过最短路两种方法解决
题目大意:
给定一堆点,具有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 排序或者通过最短路两种方法解决的更多相关文章
- 两种方法解决 "The License CNEKJPQZEX- has been cancelled..." 问题
今天在使用 2017 的 IDEA 和 Pycharm 等IDE的时候,提示了如题的问题.之前实在 http://idea.lanyus.com/ 网站点击生成注册码,复制粘贴到 IDEA 中就好了, ...
- 两种方法解决tomcat的 Failed to initialize end point associated with ProtocolHandler ["http-apr-8080"]
出现这种原因主要是8080端口被占用了. 解决1: 打开任务管理器看看里面有没有javaw的线程,把它关了再重新启动tomcat看看. 解决2: 修改tomcat /conf /server.xml ...
- 解决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' ...
- 转:python list排序的两种方法及实例讲解
对List进行排序,Python提供了两个方法 方法1.用List的内建函数list.sort进行排序 list.sort(func=None, key=None, reverse=False) Py ...
- 用Java集合中的Collections.sort方法对list排序的两种方法
用Collections.sort方法对list排序有两种方法第一种是list中的对象实现Comparable接口,如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
- python list排序的两种方法及实例讲解
对List进行排序,Python提供了两个方法方法1 用List的内建函数list sort进行排序list sort(func=None, key=None, reverse=False)Pytho ...
- MongoDB实现分页(两种方法)
1.插入实验数据 偷懒用下samus,100条. ; i < ; i++) { Document doc = new Document(); doc["ID"] = i; d ...
- 计算理论:NFA转DFA的两种方法
本文将以两种方法实现NFA转DFA,并利用C语言实现. 方法二已利用HNU OJ系统验证,方法一迷之WA,但思路应该是对的,自试方案,测试均通过. (主要是思路,AC均浮云,大概又有什么奇怪的Case ...
- MySQL中删除数据的两种方法
转自:http://blog.csdn.net/apache6/article/details/2778878 1. 在MySQL中有两种方法可以删除数据: 一种是delete语句,另一种是trunc ...
随机推荐
- J20170527-ts
足場 立脚点.脚手架 scaffold ハイパーリンク 超链接 hyperlink アンカータグ 锚标签 でしゃばり 多嘴.多事.多管闲事的人,好出风头的人 でしゃばる 多管闲事 節介 ...
- bzoj 1047: [HAOI2007]理想的正方形【单调队列】
没有复杂结构甚至不长但是写起来就很想死的代码类型 原理非常简单,就是用先用单调队列处理出mn1[i][j]表示i行的j到j+k-1列的最小值,mx1[i][j]表示i行的j到j+k-1列的最大值 然后 ...
- bzoj 3156: 防御准备【斜率优化dp】
就是套路咯,设s[i]为1+2+...i 首先列出dp方程\( f[i]=min(f[j]+a[i]+(i-j)*i-(s[i]-s[j])) \) 然后推一推 \[ f[i]=f[j]+a[i]+( ...
- bzoj1052覆盖问题(二分+贪心)
1052: [HAOI2007]覆盖问题 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2446 Solved: 1131[Submit][Stat ...
- [Swift通天遁地]二、表格表单-(1)创建自定义的UITableViewCell(单元格类)
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- Photoshop CC2019破解版
Photoshop CC2019 精简版: 链接:https://pan.baidu.com/s/1PeFrhtLHxLRXCW_vMkAZDg 提取码:q6nl Photoshop CC2019: ...
- webpack+vue-cli中proxyTable配置接口地址代理详细解释
在vue-cli项目中config目录里面的index.js配置接口地址代理,详细解释如下图所示:
- Java多线程(五)停止线程 在沉睡中停止线程
在沉睡中停止线程会抛出异常 public class SleepInterruptDemo extends Thread { public void run() { super.run(); try ...
- 常用点击事件(鼠标、光标、键盘、body)
常用事件: 鼠标: onclick(单击) ondblclick(双击) oncontextmenu(右击) onmouseover onmouseout 光标: onfocus onblur 键盘: ...
- 转 form表单中name和id区别
HTML文本是由HTML命令组成的描述性文本,HTML命令可以说明文字.图形.动画.声音.表格.链接等.HTML的结构包括头部(Head).主体(Body)两大部分,其中头部描述浏览器所需 ...