zoukankan      html  css  js  c++  java
  • [BZOJ]2259: [Oibh]新型计算机

    题解:难点在于建图  首先有个很显然的思路  就是

          $$ i ightarrow i+a[i]+1left ( i+a[i]<=n ight ) $$  边权为0

             $$ i ightarrow n+1left ( i+a[i]>n ight ) $$ 边权为 $ i+a[i]-n $

    然后就是  他有偏移量  就是可以对于 a[i]进行变化  这样我们可以对于 $ i+a[i]+1 $往左右分别连边 边权为1  保证不会连重边 这样会保证建边总数小于等于3*n

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=1e6+10;
    const double eps=1e-8;
    #define ll long long
    const ll inf=1e18;
    using namespace std;
    struct edge{int t,v;edge*next;}e[MAXN*3],*h[MAXN],*o=e;
    void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    
    
    
    int a[MAXN];
    bool lvis[MAXN],rvis[MAXN],vis[MAXN];
    ll dis[MAXN];
    typedef struct node{
        int v;ll d;
        friend bool operator<(node aa,node bb){return aa.d>bb.d;}
    }node;
    priority_queue<node>que;
    int main(){
        int n=read();
        inc(i,1,n)a[i]=read();
        inc(i,1,n){
    	if(i+a[i]+1>n+1){add(i,n+1,i+a[i]-n);continue;}
    	add(i,i+a[i]+1,0);
    	int j=i+a[i]+1;
    	while(j>i+1&&!lvis[j])add(j,j-1,1),lvis[j]=1,j--;
    	j=i+a[i]+1;
    	while(j<n+1&&!rvis[j])add(j,j+1,1),rvis[j]=1,j++;
        }
        inc(i,1,n+1)dis[i]=inf;
        que.push((node){1,0});dis[1]=0;
        while(!que.empty()){
    	node t=que.top();que.pop();
    	if(vis[t.v])continue;
    	vis[t.v]=1;
    	link(t.v){
    	    if(dis[j->t]>dis[t.v]+j->v){
    		dis[j->t]=dis[t.v]+j->v;
    		que.push((node){j->t,dis[j->t]});
    	    }
    	}
        }
        printf("%lld
    ",dis[n+1]);
    }
    

      

    2259: [Oibh]新型计算机

    Time Limit: 6 Sec  Memory Limit: 128 MB
    Submit: 746  Solved: 236
    [Submit][Status][Discuss]

    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
  • 相关阅读:
    苹果一体机发射Wi-Fi
    iphone 屏蔽系统自动更新,消除设置上的小红点
    data parameter is nil 异常处理
    copy与mutableCopy的区别总结
    java axis2 webservice
    mysql 远程 ip访问
    mysql 存储过程小问题
    mysql游标错误
    is not writable or has an invalid setter method错误的解决
    Struts2中关于"There is no Action mapped for namespace / and action name"的总结
  • 原文地址:https://www.cnblogs.com/wang9897/p/10349081.html
Copyright © 2011-2022 走看看