【题】【(堆/线段树/树状数组优化DP)/图论】NKOJ 3485 数据
来源:互联网 发布:java特种兵 编辑:程序博客网 时间:2024/04/29 16:41
NKOJ 3485 数据
时间限制 : 30000 MS 空间限制 : 165536 KB
问题描述
Mr_H 出了一道信息学竞赛题,就是给 n 个数排序。输入格式是这样的:
试题有若干组数据。每组数据的第一个是一个整数 n,表示总共有 n 个数待排序;接下来 n 个整数,分别表示这n 个待排序的数。
例如:3 4 2 –1 4 1 2 3 4,就表示有两组数据。第一组有3 个数(4,2,-1),第二组有4个数(1,2,3,4)。可是现在Mr_H 做的输入数据出了一些问题。
例如:2 1 9 3 2 按理说第一组数据有2 个数(1,9),第二组数据有3 个数,可是“3”后面并没有出现三个数,只出现了一个数“2”而已!
现在 Mr_H 需要对数据进行修改,改动中“一步”的含义是对文件中的某一个数+1 或-1,写个
程序,计算最少需要多少步才能将数据改得合法。
输入格式
第一行一个整数m,表示Mr_H 做的输入数据包含的整数个数。第二行包含m 个整数a[i],每个整数的绝对值不超过10000。
输出格式
一个整数,表示把数据修改为合法的情况下,最少需要多少步。
样例输入
【样例输入1】
4
1 9 3 2
【样例输入2】
10
4 4 3 5 0 -4 -2 -1 3 5
样例输出
【样例输出1】
2
【样例输出2】
3
提示
【数据范围】
对于 20%的数据,m<=10, |a[i]|<=5;
对于60%的数据,m<=5000, |a[i]|<=10000
对于100%的数据,m<=100000, |a[i]|<=10000
来源 【2015多校联训4】 by YZ
法一,图论:
因为a[i]>=0时,i可以无损耗到达i+a[i]+1号节点,所以连一条权值为0单向边,注意终点可能超过n+1号,也是合法的。
因为一个节点到达k号后,往左或往右一格均视为操作一次,所以各个节点向左右连一条双向边,注意包括超过n+1的点。且第一个点与第二个点不连。
若a[1]<0 ,则至少需要 -a[i]的操作数,所以强行将a[1]改为0,并答案强制加-a[1]。
最后找出1到n+1的最短路
/*图论*/#include<cstdio>#include<queue> #include<vector>#include<iostream>using namespace std;const int need=110003;const int inf=1e9; int n,nn;//.....................................inline void in_(int &d){ char t=getchar();bool mark=false; while(t<'0'||t>'9') {if(t=='-') mark=true;t=getchar();} for(d=0;!(t<'0'||t>'9');t=getchar()) d=(d<<1)+(d<<3)+t-'0'; if(mark) d=-d;}//.....................................struct bian{ int la,en,len;};vector<bian> w;#define pb(a,b,c) push_back((bian){a,b,c})int tot,fi[need];void add(const int &a,const int &b,const int &c){ tot++; w.pb(fi[a],b,c); fi[a]=tot;} //.....................................int s,e;struct fy{ int dis,id; bool operator< (const fy &b) const { return dis>b.dis; }};priority_queue<fy> q;#define pu(a,b) push((fy){a,b}) bool getans[need];int dis[need];void dijkstra(int s){ for(int i=1;i<=nn;i++) dis[i]=inf,getans[i]=false; q.pu(0,s),dis[s]=0; int x,y,t; while(!q.empty()) { while(!q.empty()&&getans[q.top().id]) q.pop(); x=q.top().id; if(x==e) return ; getans[x]=true; q.pop(); for(t=fi[x];t;t=w[t].la) { y=w[t].en; if(getans[y]) continue; if(dis[y]>dis[x]+w[t].len) { dis[y]=dis[x]+w[t].len; q.pu(dis[y],y); } } }}//.....................................int main(){ w.resize(1); int n;scanf("%d",&n); int dans=0; int a; in_(a); if(a<0) dans=-a,add(1,2,0); else add(1,a+2,0); nn=max(nn,a+2); for(int i=2,a;i<=n;i++) { in_(a); if(a>=0) add(i,i+a+1,0); nn=max(nn,i+a+1); add(i,i+1,1),add(i+1,i,1); } for(int i=n+1;i<=nn;i++) add(i,i+1,1),add(i+1,i,1); s=1,e=n+1; dijkstra(s); cout<<dis[e]+dans;}
法二-1:堆优化动规
#include<cstdio>#include<set>#include<iostream>#include<queue>using namespace std;const int need=100003;const int inf=1e9;int a[need];int f[need];struct fy{ int val,key; friend bool operator< (const fy a,const fy &b) { //if(a.val==b.val) return a.key<b.key; return a.val>b.val; }};priority_queue<fy> q1;#define pu(a,b) push((fy){a,b}) int q2=inf;//............................................inline void in_(int &d){ char t=getchar();bool mark=false; while(t<'0'||t>'9') {if(t=='-') mark=true;t=getchar();} for(d=0;!(t<'0'||t>'9');t=getchar()) d=(d<<1)+(d<<3)+t-'0'; if(mark) d=-d;}//............................................int main(){ int n;scanf("%d",&n); for(int i=1;i<=n;i++) in_(a[i]); q1.pu(a[1]+1,a[1]+1); for(int i=1;i<=n;i++) { //cout<<q1.top().key; while(!q1.empty()&&q1.top().key<=i) { q2=min(q1.top().val-2*q1.top().key,q2); q1.pop(); //cout<<q1.size(); } f[i]=q2+i; if(!q1.empty()) f[i]=min(f[i],q1.top().val-i); q1.pu(f[i]+a[i+1]+i+1,a[i+1]+i+1); } cout<<f[n];}
- 【题】【(堆/线段树/树状数组优化DP)/图论】NKOJ 3485 数据
- zoj 3349 简单DP 线段树或树状数组优化
- #bzoj2933#【重庆市NOIP模拟赛】数据(DP线段树优化 or DP堆优化 + 证明)
- NKOJ 2182 (HEOI 2012) 采花(树状数组/线段树)
- hdu2227 Find the nondecreasing subsequences(dp+线段树or树状数组优化)
- 【DP】【线段树】【树状数组】saber 题解
- 【题】【树状数组】NKOJ 3702 打鼹鼠
- codeforces 629D-Babaei and Birthday Cake(dp && 线段树或树状数组离散优化)
- 数据--dp,线段树优化
- HDU - 4991(树状数组优化 dp)
- bzoj4361 isn(树状数组优化DP)
- hdu 5542(树状数组优化dp)
- HDU 5542 (DP+树状数组优化)
- HDU5542(树状数组优化DP)
- hdu5542(树状数组优化dp)
- bzoj 3594(树状数组优化dp)
- 【HDU4991】dp 树状数组优化
- hdu5542 树状数组优化dp
- c程序设计语言 习题1-9
- 集合
- NYOJ - 42 - 一笔画问题(欧拉回路,DFS)
- C#49课的主要内容
- 51nod-【1013 3的幂的和】
- 【题】【(堆/线段树/树状数组优化DP)/图论】NKOJ 3485 数据
- 面向对象之依赖、组合、聚合
- eclipse中查看源码方法
- 单向散列加密,对称加密,非对称加密
- 洛谷 https://www.luogu.org/problem/show?pid=T574
- 代码规范工具-Checkstyle使用手册
- 一种简单粗暴的数据层网络缓存(二)实现方案
- 11月第二周周报
- Java 深究字符串String类(2)之重写toString()方法无意识递归