• 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

  • 相关阅读:
    waitkey();
    一、数组--删除排序数组中的重复项
    core组件进阶
    opencv数据结构与基本绘图
    highGUI图形用户界面
    合并两个有序链表
    字符串
    内存
    9位运算
    8设备文件
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12149126.html
Copyright © 2020-2023  润新知