BZOJ_2259_ [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


 

暴力的话从i到i+a[i]+1连一条0的边,向两边连对应代价的边。

这样边数是O(n^2)的,考虑只保留有用的边,只保留i->i+1(1)或i->i-1(1)。

首先,从左到右的边一定都连,因为a[i]>=0。

从右往左的边只保留一部分,即从最小的i+a[i]+1开始,到最后。

这样连边就没问题了,跑dij即可。

 

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds;
#define N 1000050
inline char nc() {
	static char buf[100000],*p1,*p2;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
int rd() {
	int x=0; char s=nc();
	while(s<'0'||s>'9') s=nc();
	while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
	return x;
}
int n,is[N],head[N],to[N<<2],nxt[N<<2],val[N<<2],cnt,a[N],dis[N],vis[N];
inline void add(int u,int v,int w) {
	to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w;
}
__gnu_pbds::priority_queue<pair<int,int> >q;
int main() {
	n=rd();
	int i,x,mn=1<<30;	
	for(i=1;i<=n;i++) {
		a[i]=rd();
		x=i+a[i]+1;
		if(x<=n+1) add(i,x,0);
		else add(i,n+1,x-n-1);
		mn=min(mn,x);
	}
	for(i=2;i<=n;i++) add(i,i-1,1);
	for(i=mn;i<=n;i++) add(i,i+1,1); 
	memset(dis,0x3f,sizeof(dis)); 
	dis[1]=0;
	q.push(make_pair(0,1));
	while(!q.empty()) {
		x=q.top().second; q.pop();
		if(vis[x]) continue;
		vis[x]=1;
		for(i=head[x];i;i=nxt[i]) {
			if(dis[to[i]]>dis[x]+val[i]) {
				dis[to[i]]=dis[x]+val[i];
				q.push(make_pair(-dis[to[i]],to[i]));
			}
		}
	}
	printf("%d\n",dis[n+1]);
}

 

posted @ 2018-08-05 21:12  fcwww  阅读(231)  评论(0编辑  收藏  举报