dfs
就假如当前有N层楼要确认,K个鸡蛋。那么枚举当前鸡蛋放在x后变成了两个子问题dfs(x-1,k-1),dfs(n-x,k),dfs就好。复杂度为O(nkn)状态数枚举次数
考虑到dp[N][K]随着N递增而递增,所以固定k对所有x画图后发现 dfs(x-1,k-1)递增,dfs(n-x,k) 递减。那么要想使他俩的最大值最小直接二分就可以了(找到最后一个L使得dfs(L-1,K-1)《=dfs(N-L,K) 和最小的R(前面的式子返回来))。
复杂度O(NK*log(n))
class Solution {
unordered_map<int,int>M;
int dfs(int N,int K) {
if(M.find(N*1000+K)==M.end()) {
int ans;
if(N==0) ans=0;
else if(K==1) ans=N;
else {
int l=1,r=N;
while(l+1<r) {
int mid=(l+r)/2;
int t1=dfs(mid-1,K-1);
int t2=dfs(N-mid,K);
if(t1<t2) l=mid;
else if(t1>t2) r=mid;
else {
l=r=mid;
}
}
ans=1+min(max(dfs(l-1,K-1),dfs(N-l,K)),max(dfs(N-r,K),dfs(r-1,K-1)));
}
M[N*1000+K]=ans;
}
return M[N*1000+K];
}
public:
int superEggDrop(int K, int N) {
return dfs(N,K);
}
};
dp
注意到对于dp[K][N] 的最优决策点一定在dp[K][N-1]的最优决策点右边,所以可以O(n*k)直接dp
口胡证明:设dp[k][n-1]的决策点为x,那么dp[k][n]的所有决策点的递增函数和dp[k][n-1]的递增函数图像是一致的(前n-1个),而递减图像为dp[k][n-1]的递减图像上移一定单位得到的,所以最优决策点,也就是交点,一定是向右移动的。
那么我们在dp的时候维护一个最优决策点的位置就好了
class Solution {
unordered_map<int,int>M;
int dfs(int N,int K) {
vector<int>dp(N+1);
for(int i=0;i<=N;i++) dp[i]=i;
for(int k=2;k<=K;k++) {
vector<int>new_dp(N+1,0);
int x=1;
for(int i=1;i<=N;i++) {
while(x+1<=i&&max(dp[x-1],new_dp[i-x])>=max(dp[x],new_dp[i-x-1])) x++;
new_dp[i]=max(dp[x-1],new_dp[i-x]) +1;
}
swap(dp,new_dp);
}
return dp[N];
}
public:
int superEggDrop(int K, int N) {
return dfs(N,K);
}
};