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;
}
posted @ 2018-10-07 12:24  Dream_maker_yk  阅读(308)  评论(0编辑  收藏  举报