• BZOJ2259 [Oibh]新型计算机 【傻逼最短路】


    Description

    Tim正在摆弄着他设计的“计算机”,他认为这台计算机原理很独特,因此利用它可以解决许多难题。
    但是,有一个难题他却解决不了,是这台计算机的输入问题。新型计算机的输入也很独特,假设输入序列中有一些数字(都是自然数——自然数包括0),计算机先读取第一个数字S1,然后顺序向后读入S1个数字。接着再读一个数字S2,顺序向后读入S2个数字……依此类推。不过只有计算机正好将输入序列中的数字读完,它才能正确处理数据,否则计算机就会进行自毁性操作!
    Tim现在有一串输入序列。但可能不是合法的,也就是可能会对计算机造成破坏。于是他想对序列中的每一个数字做一些更改,加上一个数或者减去一个数,当然,仍然保持其为自然数。使得更改后的序列为一个新型计算机可以接受的合法序列。
    不过Tim还希望更改的总代价最小,所谓总代价,就是对序列中每一个数操作的参数的绝对值之和。
    写一个程序:
     从文件中读入原始的输入序列;
     计算将输入序列改变为合法序列需要的最小代价;
     向输出文件打印结果。

    Input

    输入文件包含两行,第一行一个正整数N,N<1 000 001。
    输入文件第二行包含N个自然数,表示输入序列。

    Output

    仅一个整数,表示把输入序列改变为合法序列需要的最小代价,保证最小代价小于109。

    Sample Input

    4
    2 2 2 2

    Sample Output

    1


    思路

    傻子最短路
    直接发现加一减一和移动绝对值的位置是等价的
    就在有可能贡献的区间内把相邻节点连上边就可以了
    然后傻逼最短路


    //Author: dream_maker
    #include<bits/stdc++.h>
    using namespace std;
    //----------------------------------------------
    //typename
    typedef long long ll;
    //convenient for
    #define fu(a, b, c) for (int a = b; a <= c; ++a)
    #define fd(a, b, c) for (int a = b; a >= c; --a)
    #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
    //inf of different typename
    const int INF_of_int = 1e9;
    const ll INF_of_ll = 1e18;
    //fast read and write
    template <typename T>
    void Read(T &x) {
      bool w = 1;x = 0;
      char c = getchar();
      while (!isdigit(c) && c != '-') c = getchar();
      if (c == '-') w = 0, c = getchar();
      while (isdigit(c)) {
        x = (x<<1) + (x<<3) + c -'0';
        c = getchar();
      }
      if (!w) x = -x;
    }
    template <typename T>
    void Write(T x) {
      if (x < 0) {
        putchar('-');
        x = -x; 
      }
      if (x > 9) Write(x / 10);
      putchar(x % 10 + '0');
    }
    //----------------------------------------------
    const int N = 1e6 + 10;
    struct Edge{
      int v, w, nxt;
      Edge(int v = 0, int w = 0, int nxt = 0):v(v), w(w), nxt(nxt) {};
    }E[N * 6];
    int head[N], tot = 0;
    int inq[N], dis[N];
    int pre[N], nxt[N], a[N], n;
    void add(int u, int v, int w) {
      E[++tot] = Edge(v, w, head[u]);
      head[u] = tot;
    }
    void spfa() {
      memset(dis, 0x3f, sizeof(dis));
      queue<int> q;
      q.push(1);
      dis[1] = 0;
      while (!q.empty()) {
        int u = q.front(); q.pop();
        inq[u] = 0;
        for(int i = head[u]; i; i = E[i].nxt) {
          int v = E[i].v;
          if (dis[v] > dis[u] + E[i].w) {
            dis[v] = dis[u] + E[i].w;
            if (!inq[v]) inq[v] = 1, q.push(v);
          }
        }
      }
    }
    int main() {
      Read(n);
      fu(i, 1, n) {
        Read(a[i]);
        fu(j, i + 1, min(i + a[i] + 1,n)) {
          if (pre[j]) break;
          pre[j] = 1;
          add(j, j - 1, 1);
            }
        fu(j, i + a[i] + 1, n) {
          if (nxt[j]) break;
          nxt[j] = 1;
          add(j, j + 1, 1);
        }
        if (i + a[i] <= n) add(i, i + a[i] + 1, 0);
        else add(i, n + 1, a[i] + i - n);
      }
      spfa();
      Write(dis[n + 1]);
      return 0;
    }
    
  • 相关阅读:
    关于换行的问题
    Ubuntu 18.4 查看CUDNN版本
    opencv bgr转rgb
    python读写json文件
    timm库,PyTorchImageModels,简称timm,是一个巨大的PyTorch代码集合
    用SQL创建数据库登录用户
    《dsu on tree》深度剖析
    C#调用DLL报错:试图加载格式不正确的程序
    【项目】项目147
    【项目】项目148
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9749810.html
Copyright © 2020-2023  润新知