zoukankan      html  css  js  c++  java
  • 20200104模拟赛 问题C 上台拿衣服

    题目

    分析:

    乍一看不就是从楼上扔鸡蛋那道题吗。。。

    然后开始写写写。。。

    设f [ i ] [ j ]表示 i 个记者膜 j 次可以验证多少层楼。。。

    于是开始递推:

    我们选取第 i 个记者去尝试其中一层楼y

    如果他被续了(续和膜蛤是sm意思啊2333

    /*龙门粗口*/

    如果他被续了,那么说明x<y,然后研究子问题f [ i-1 ] [ j-1 ]

    如果他没被续,那么说明x>=y,然后研究子问题f [ i ] [ j-1 ]

    包括自己所在这层楼,所以递推式为:

    f [ i ] [ j ] = f [ i ] [ j-1 ] + f [ i-1 ] [ j-1 ] + 1

    于是我们可以预处理出答案,然后询问时lowerbound就好了。。。

    我记得当时开的f[64][64]来着。。。

    开了,美滋滋。。。。

    一个小时后。。。

    不对!!!!

    这样连n=100,k=1都算不对?!

    突然想起原题有这样一个限制,如果尝试次数超过64就直接输出-1!

    差点翻车。。。

    于是就往大了开

    开到了f[64][100000]

    这样能算多少呢。。。

    嗯,当k>3时,都是算的出来的。。。

    那么找一下k=1,2,3的规律吧。。

    k=1时,ans就是n

    k=2时,ans满足ans*(ans+1)/2>=n

    k=3时。。。

    不会诶。。。

    那么为3新开一个怎么样

    又开了个g[3][3000000]

    咦,跑出来了,稳了。。。

    结果。。。

    枯了出来。。。

    真该死啊,改小一点就过了。。。

    但是这道题的奇奇怪怪的技巧有必要记一下2333

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    
    #define maxn 100005
    #define maxm 65
    #define INF 1000000000000000000ll
    
    using namespace std;
    
    inline long long getint()
    {
        long long num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
    
    long long f[maxm][maxn];
    long long g[4][20*maxn];
    long long N,K;
    
    inline void init()
    {
        for(int i=1;i<maxm;i++)for(int j=1;j<maxn;j++)f[i][j]=min(f[i][j-1]+f[i-1][j-1]+1,INF);
        for(int i=1;i<=3;i++)for(int j=1;j<20*maxn;j++)g[i][j]=min(g[i][j-1]+g[i-1][j-1]+1,INF);
    }
    
    inline void solve(long long N)
    {
        long long l=1,r=1ll<<31;
        while(l<r)
        {
            long long mid=(l+r)>>1;
            if(1ll*mid*(mid+1)/2<N)l=mid+1;
            else r=mid;
        }
        printf("%lld
    ",l);
    }
    
    int main()
    {
        int T=getint();
        init();
        while(T--)
        {
            N=getint(),K=getint();
            if(K==1)printf("%lld
    ",N);
            else if(K==2)solve(N);
            else if(K==3)printf("%d
    ",lower_bound(g[K]+1,g[K]+20*maxn,N)-g[K]);
            else printf("%d
    ",lower_bound(f[K]+1,f[K]+maxn,N)-f[K]);
        }
    }
    View Code

  • 相关阅读:
    MySQL-基本sql命令
    Java for LeetCode 203 Remove Linked List Elements
    Java for LeetCode 202 Happy Number
    Java for LeetCode 201 Bitwise AND of Numbers Range
    Java for LeetCode 200 Number of Islands
    Java for LeetCode 199 Binary Tree Right Side View
    Java for LeetCode 198 House Robber
    Java for LeetCode 191 Number of 1 Bits
    Java for LeetCode 190 Reverse Bits
    Java for LeetCode 189 Rotate Array
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12149126.html
Copyright © 2011-2022 走看看