sincerit 飞翔

飞翔
时间限制:3000 ms | 内存限制:65535 KB
难度:4
描述
鹰最骄傲的就是翱翔,但是鹰们互相都很嫉妒别的鹰比自己飞的快,更嫉妒其他的鹰比自己飞行的有技巧。于是,他们决定举办一场比赛,比赛的地方将在一个迷宫之中。

这些鹰的起始点被设在一个N*M矩阵的左下角map[1,1]的左下角。终点被设定在矩阵的右上角map[N,M]的右上角,有些map[i,j]是可以从中间穿越的。每一个方格的边长都是100米。如图所示:

在这里插入图片描述

没有障碍,也没有死路。这样设计主要是为了高速飞行的鹰们不要发现死路来不及调整而发生意外。潘帕斯雄鹰冒着减RP的危险从比赛承办方戒备森严的基地中偷来了施工的地图。但是问题也随之而来,他必须在比赛开始之前把地图的每一条路都搞清楚,从中找到一条到达终点最近的路。(哈哈,笨鸟不先飞也要拿冠军)但是此鹰是前无古鹰,后无来鹰的吃菜长大的鹰–菜鸟。他自己没有办法得出最短的路径,于是紧急之下找到了学OI的你,希望找到你的帮助。

输入
本题有多组数据。以EOF为输入结束的标志。
每组测试数据的首行为n,m(0<n,m<=1000000),第2行为k(0<k<=1000)表示有多少个特殊的边。以下k行为两个数,i,j表示map[i,j]是可以直接穿越的。
输出
仅一行,1,1–>n,m的最短路径的长度,四舍五入保留到整数即可
样例输入
3 2
3
1 1
3 2
1 2
样例输出
383

求特殊线段的递增子序列的最大长度

#include <stdio.h>
#include <cstring>
#include <math.h>
#include <iostream>
#include <algorithm>
#define N 1000000
using namespace std;
struct node {
  int x, y;
};
int dp[N+5];
node p[1005];
int LIS(int k) {
  int mx = 0;
  for (int i = 0; i < k; i++) dp[i] = 1;
  for (int i = 1; i < k; i++) {
    for (int j = 0; j < i; j++) {
      if (p[i].x > p[j].x && p[i].y > p[j].y && dp[i] < dp[j]+1) {
        dp[i] = dp[j] + 1;
        if (mx < dp[i]) mx = dp[i];
      }
    }
  }
  return mx;
}
bool cmp(node a, node b) {
  if (a.x != b.x) return a.x < b.x;
  return a.y < b.y;
}
int main() {
  int n, m;
  while (~scanf("%d%d", &n, &m)) {
    int k;
    scanf("%d", &k);
    for (int i = 0; i < k; i++) scanf("%d %d", &p[i].x, &p[i].y);
    //sort(p, p+k, cmp);
    int s = LIS(k);
    double ans = (n + m - 2 * s) * 100 + sqrt(2) * 100 * s + 0.5; // 精度问题用1.414不行 
    printf("%d\n", int(ans));
  }
  return 0;
}
/*
为什么要排序
求最长递增子序列是跟输入数据的先后顺序有关的,比如1234长为4,而4321长为1
要的到最长的所以要先排序
*/ 

还有一种做法不知道为什么错了
留着以后看看

#include <stdio.h>
#include <cstring>
#include <math.h>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int n, m; // 表示列行
struct node {
  int x, y;
  friend bool operator<(const node& a, const node& b) {
    if (a.x != b.x) return a.x > b.x;
    return a.y > b.y;
  }
};

int main() {
  while (~scanf("%d %d", &n, &m)) {
    int k, x, y;
    priority_queue<node> que;
    scanf("%d", &k);
    for (int i = 0; i < k; i++) {
      scanf("%d%d", &x, &y);
      node t;
      t.x = x; t.y = y;
      que.push(t);
    }
    node temp = que.top();
    que.pop();
    int sum = 1;
    /*while (que.size()) {
      node w = que.top();
      printf("%d %d\n", w.x, w.y);
      que.pop();
    }*/
    while (que.size()) {
      node ss = que.top();
      if (ss.x > temp.x && ss.y > temp.y) {
        temp.x = ss.x;
        temp.y = ss.y;
        sum++;
      }
      que.pop();
    }
    double len = (n + m - 2 * sum) * 100 +  100 * sqrt(2) * sum + 0.5; 
    printf("%d\n", int(len));
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/sincerit/article/details/84592240