zoukankan      html  css  js  c++  java
  • luogu P3645 [APIO2015]雅加达的摩天楼 分块 根号分治

    LINK:雅加达的摩天楼

    容易想到设(f_{i,j})表示第i个(doge)在第j层楼的最小步数.

    转移显然是bfs.值得一提的是把初始某层的(doge)加入队列 然后转移边权全为1不需要 双端队列的bfs.

    复杂度为状态数量(ncdot m)

    可以发现 可能有两个(doge)跳在同一层楼 且 跳跃能力相同 显然其中一个一定没用 可以进行一些小优化 将状态改写成(f_{i,j})到达第i层楼跳跃能力为j的最小步数.

    复杂度(ncdot sqrt n) 证明和另外一种解法如下:

    观察(n)(30000)容易想到利用分块来解决问题.

    把跳跃能力和(B=sqrt n)做比较,可以当跳跃能力(p_i<=B)时 将这种能力在图中的边连接 边数最坏为(ncdot B)

    (p_i>B)时 最坏可跳位置只有(frac{n}{B})个 此时边数为(mcdot frac{n}{B})(mcdot B)

    可以得到边数的数量级为(ncdot B) 也就是到达某个点的状态(i,j)跳跃能力为j这样的二元组只有(ncdot B)个.

    (f_{i,j})表示到达第i层楼此时跳跃能力为j的最小步数。

    直接bfs即可 复杂度为状态数(ncdot B)

    code
    //#include<bits/stdc++.h>
    #include<iostream>
    #include<queue>
    #include<iomanip>
    #include<cctype>
    #include<cstdio>
    #include<deque>
    #include<utility>
    #include<cmath>
    #include<ctime>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<vector>
    #include<algorithm>
    #include<stack>
    #include<map>
    #include<set>
    #include<bitset>
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)>(y)?(y):(x))
    #define INF 1000000000
    #define ll long long
    #define db double
    #define mod 1000000007
    #define pii pair<ll,ll>
    #define mk make_pair
    #define us unsigned
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc()
    {
        return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
    	int x=0,f=1;char ch=getc();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
        return x*f;
    }
    const int MAXN=30010;
    int n,m,ans=-1,st,en;
    int vis[MAXN];
    vector<int>g[MAXN];
    bitset<MAXN>w[MAXN];
    struct wy
    {
    	int x,p;
    	int v;
    };
    queue<wy> q;
    inline void insert(int x,int c,int v)
    {
    	if(!w[x][c]){q.push((wy){x,c,v});w[x][c]=1;}
    	if(vis[x])return;
    	for(us int i=0;i<g[x].size();++i)
    	{
    		int tn=g[x][i];
    		if(!w[x][tn])
    		{
    			q.push((wy){x,tn,v});
    			w[x][tn]=1;
    		}
    	}
    	vis[x]=1;
    }
    inline void bfs()
    {
    	while(q.size())
    	{
    		wy a=q.front();q.pop();
    		if(a.x==en){ans=a.v;return;}
    		if(a.x-a.p>=0)insert(a.x-a.p,a.p,a.v+1);
    		if(a.x+a.p<n)insert(a.x+a.p,a.p,a.v+1);
    	}
    }
    int main()
    {
    	//freopen("1.in","r",stdin);
    	n=read();m=read();
    	for(int i=1;i<=m;++i)
    	{
    		int x,p;
    		x=read();p=read();
    		if(i==1)st=x;
    		if(i==2)en=x;
    		g[x].push_back(p);
    	}
    	vis[st]=1;
    	for(us int i=0;i<g[st].size();++i)
    	{
    		int tn=g[st][i];
    		if(!w[st][tn])
    		{
    			q.push((wy){st,tn,0});
    			w[st][tn]=1;
    		}
    	}
    	bfs();
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    HDU 1520 Anniversary party(简单树形DP)
    HDU 4398 Template Library Management(贪心,STL)
    HDU 2829 Lawrence(斜率优化DP)
    HDU 2993 MAX Average Problem(斜率优化DP)
    HDU 3507 Print Article(斜率DP优化)
    转:操作系统各大公司笔试题汇总
    转载 ANSI、Unicode、UTF8相互转化的函数
    2011 各大IT公司笔试面试题目
    Windows Media Format SDK系统概述
    limits.h
  • 原文地址:https://www.cnblogs.com/chdy/p/13346262.html
Copyright © 2011-2022 走看看