• 鹰蛋


    C:不能更经典的经典DP题
    Description:
    有一堆共k个鹰蛋,一位教授想研究这些鹰蛋的坚硬度E。他是通过不断从一幢n层的楼上向下扔鹰蛋来确定E的。
    当鹰蛋从第E层楼及以下楼层落下时是不会碎的,但从第(E+1)层楼及以上楼层向下落时会摔碎。
    如果鹰蛋未摔碎,还可以继续使用;但如果鹰蛋全碎了却仍未确定E,这显然是一个失败的实验。教授希望实验是成功的。
    例如:若鹰蛋从第1层楼落下即摔碎,E=0;若鹰蛋从第N层楼落下仍未碎,E=N。
    这里假设所有的鹰蛋都具有相同的坚硬度。给定鹰蛋个数k与楼层数n。
    要求最坏情况下确定E所需要的最少次数。
    Solution:
    正常DP,(dp[i][j])i层,j个鹰蛋,最少次数,(dp[i][j]=min(dp[k][j-1],dp[i-k][j])+1),让两边尽量相等,可以二分,但是这个dp空间存不下,时间也是(n^{2}log_n),考虑把存不下的那一维和值调换,也就是(dp[i][j])i次,j个鹰蛋,可到达最大层数,由刚才转移可得,(dp[i][j]=dp[i-1][j]+dp[i-1][j-1]),这样一般的也过了,但是1和2个鹰蛋仍然存不下,如果k=1,ans=n,如果k=2,由dp思想,要使两边相等,就右边一个区间等于左边一个区间长度-1,最后到1结束,ans=t,t*(t+1)>=n的最小值。

    #include<bits/stdc++.h>
    #define LL long long
    #define inf 1e18
    using namespace std;
    vector<LL> G[65];
    int T,k;
    LL n;
    int main() {
    	G[3].push_back(0);
    	LL x=1;
    	while(1) {
    		G[3].push_back(G[3][x-1]+1+(x-1)*x/2);
    		if(G[3].back()>=inf) break;
    		x++;
    	}
    	for(int i=4;i<=64;i++) {
    		int x=1;
    		G[i].push_back(0);
    		while(1) {
    			G[i].push_back(G[i][x-1]+1+G[i-1][x-1]);
    			if(G[i].back()>=inf) break;
    			x++;
    		}
    	}
    	scanf("%d",&T);
    	while(T--) {
    		scanf("%lld%d",&n,&k);
    		if(k==1) printf("%lld
    ",n);
    		else if(k==2) {
    			n<<=1;
    			LL t=sqrt(n);
    			while(t*(t+1)<n) t++;
    			printf("%lld
    ",t);
    		}
    		else {
    			int res=lower_bound(G[k].begin(),G[k].end(),n)-G[k].begin();
    			printf("%d
    ",res);
    		}
    	}
    	return 0;
    }
    

    小结:
    1.打表找规律;
    2.dp状态过大考虑与值调换。

  • 相关阅读:
    云服务器
    Linux 安装python3.7.0
    python 读写excel(xls格式)
    常规问题解决:File "/usr/bin/yum", line 30 及 File "/usr/libexec/urlgrabber-ext-down", line 28
    pyqt5--TableWidGet
    标准库中的装饰器 lru_cache和全新的 singledispatch
    python 导入导出依赖包命令
    python的with语法的深入理解
    时间序列(四) 预测
    时间序列 ARIMA 模型 (三)
  • 原文地址:https://www.cnblogs.com/oierqingmo/p/15092675.html
Copyright © 2020-2023  润新知