• 【ural 1223】 Chernobyl' Eagle on a Roof 题解


    URAL-1223 Chernobyl’ Eagle on a Roof 题解

    详细的题解、dp优化的个人理解和解释可以见我的这一篇文章

    本文仅用于存放AC的代码以供参考。

    O(k*n^2) 无优化dp

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    #define REG register
    #define rep(i,a,b) for(REG int i=a;i<=b;i++)
    #define Rep(i,a,b) for(REG int i=a;i>=b;i--)
    const int INF=1e9;
    int N,K,f[20][1010];
    inline int log2(int x){
        int l=1,r=x,c=0;
        while(l<=r){
            int mid=(l+r)>>1; c++;
            if(r-mid>mid-l) l=mid+1;
            else r=mid-1;
        }
        return c;
    } 
    int main(){
        while(1){
            scanf("%d%d",&K,&N);
            if(K==N&&K==0) break;
            if(K>log2(N)){
                printf("%d
    ",log2(N)); continue;
            }
            memset(f,0,sizeof(f));
            rep(i,1,N) f[1][i]=i;
            rep(i,2,K){
                rep(j,1,N){
                    f[i][j]=INF;
                    rep(w,1,j)
                    f[i][j]=min(f[i][j],max(f[i-1][w-1],f[i][j-w])+1);
                }
            }
            printf("%d
    ",f[K][N]);
        }
        return 0;
    }
    

    O(KNlogN) 二分优化dp

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int INF=1e9,K=20,N=1010;
    inline int log2(int x){
        int l=1,r=x,c=0;
        while(l<=r){
            int mid=(l+r)>>1; c++;
            if(r-mid>mid-l) l=mid+1;
            else r=mid-1;
        }
        return c;
    }
    int k,n,a[2][N];
    int main(){
        while(scanf("%d%d",&k,&n)==2){
            if(k+n==0) break;
            int t=log2(n); 
            if(k>=t){
                printf("%d
    ",t);
                continue;
            }
            int *p=a[0],*f=a[1];
            for(int i=1;i<=n;i++) f[i]=i;
            for(int i=2;i<=k;i++){
                swap(p,f);
                for(int j=1;j<=n;j++) f[j]=0;
                f[1]=1;
                for(int j=2;j<=n;j++){
                    t=log2(j);
                    if(i>=t){ f[j]=t; continue; }
                    int l=1,r=j,mid,ans=r;
                    while(l<=r){
                        mid=(l+r)>>1;
                        if(p[mid-1]>=f[j-mid]) ans=mid,r=mid-1;
                        else l=mid+1;
                    }
                    f[j]=max(p[ans-1],f[j-ans])+1;
                    if(--ans>=1) f[j]=min(f[j],max(p[ans-1],f[j-ans])+1);
                }
            }
            printf("%d
    ",f[n]);
        }
        return 0;
    }
    

    O(KN)线性优化

    这里是没有开long long的必要的,但是我懒得改了。

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    using namespace std;
    typedef long long ll;
    inline ll log2(ll x){
        ll l=1,r=x,c=0;
        while(l<=r){
            ll mid=(l+r)>>1; c++;
            if(r-mid>mid-l) l=mid+1;
            else r=mid-1;
        }
        return c;
    }
    vector<ll> f,p; 
    int main(){
        while(1){
            ll k,n; scanf("%lld%lld",&k,&n);
            if(k+n==0) break;
            if(k>=log2(n)){ printf("%lld
    ",log2(n)); continue; }
            f.resize(n+1); 
            for(ll i=1;i<=n;i++) f[i]=i;
            for(ll i=2;i<=k;i++){
                f.swap(p); f.resize(n+1);
                ll pre=0; f[1]=1;
                for(ll j=2;j<=n;j++){
                    if(max(f[pre],p[j-pre-1])+1==f[j-1]) f[j]=f[j-1];
                    else f[j]=f[j-1]+1,pre=j-1;
                }
            }
            printf("%lld
    ",f[n]);
        }
        return 0;
    }
    

    可以过1e18大数据的算法

    #include <cstdio>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    #define REG register
    #define rep(i,a,b) for(REG int i=a;i<=b;i++)
    #define Rep(i,a,b) for(REG int i=a;i>=b;i--)
    inline char getc(){
        static char buf[1<<14],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<14,stdin),p1==p2)?EOF:*p1++;
    }
    inline ll scan(){
        REG ll x=0; REG char ch=0;
        while(ch<48) ch=getc();
        while(ch>=48) x=x*10+ch-48,ch=getc();
        return x;
    }
    inline ll log2(ll x){
        ll l=1,r=x,mid,c=0;
        while(l<=r){
            mid=(l+r)>>1; c++;
            if(mid-l>r-mid) r=mid-1;
            else l=mid+1;
        }
        return c;
    }
    const ll F=2e6,K=60,N=1e18;
    ll f[K+1][F],end[K+1];
    inline void prework(){
        rep(i,1,F-200) f[1][i]=i;
        rep(i,1,F-200){
            rep(j,2,K){
                if(end[j]) break;
                f[j][i]=f[j][i-1]+f[j-1][i-1]+1;
                if(f[j][i]>=N) end[j]=i;
            }
        } 
    }
    int main(){
        //REG int T=scan();
        prework();
        while(1){
            REG ll k=scan(),n=scan(),temp;
            if(n+k==0) break;
            if(k==1){ printf("%lld
    ",n); continue; }
            if(k==2){
                ll t=floor(sqrt(n<<1));
                if(t*(t+1)<n<<1) t++;
                printf("%lld
    ",t); continue;
            }
            temp=log2(n);
            if(k>=temp){ printf("%lld
    ",temp); continue; }
            REG int l=1,r=end[k],mid,ans;
            while(l<=r){
                mid=(l+r)>>1;
                if(f[k][mid]>=n) r=mid-1,ans=mid;
                else l=mid+1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    [LeetCode] Walls and Gates
    [LeetCode] Expression Add Operators
    [LeetCode] Inorder Successor in BST
    [LeetCode] Peeking Iterator
    [CTCI] 最小调整有序
    [LeetCode] Single Number III
    [LeetCode] Zigzag Iterator
    [LeetCode] Wiggle Sort
    android 设颜色透明值
    android android BitmapFactory报错OOM
  • 原文地址:https://www.cnblogs.com/Qing-LKY/p/ural1223-solution.html
Copyright © 2020-2023  润新知