【DP】RQNOJ107[Ural的鹰蛋实验]题解
2017-11-02 21:51
211 查看
题目概述
经典的鹰蛋问题,就因为懒所以不写了。解题报告
不知道大家第一想法是不是二维DP,反正我不是……2015年,当我还是普及组大菜鸡(现在是提高组大菜鸡)时,我看到了这道题。
然后根本不会,直到教练下发题解……
题解上是……没错……区间DP f[L][R][egg] ……
(黑历史完……)
显然所有区间都是等价的,唯一重要的是区间长度,所以可以定义 f[i][j] 表示区间长度为 i ,目前还有 j 个鹰蛋的最优解。
枚举在哪里扔,要考虑碎掉和不碎掉两种状态的最坏情况,即 max(f[i−1][j−1],f[n−i+1][j])+1 ,然后从所有最坏情况中选出最小值,得到 f[i][j] 。
然而这样效率是 O(n2m) ,显然无法承受。此时会想到明显错误但是最优的答案 p=⌈log2n⌉ ,当鸡蛋数超过 p 时,显然答案就是 p ,那么复杂度缩减为 O(n2log2n) 。
然后?其实还可以优化,但是我不会:P,可以看dalao的论文。
示例程序
记忆化大法好。#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=1000,maxm=10,MAXINT=((1<<30)-1)*2+1; int n,m,f[maxn+5][maxm+5]; inline int Log(int n) {for (int i=0;;i++) if ((1<<i)>=n) return i;} int Solve(int n,int m) { int p=Log(n);if (p<=m) return p; if (n==1) return 0;if (m==1) return n-1;if (~f [m]) return f [m]; f [m]=MAXINT; for (int i=2;i<=n;i++) { int now=max(Solve(i-1,m-1),Solve(n-i+1,m))+1; f [m]=min(f [m],now); } return f [m]; } int main() { freopen("program.in","r",stdin); freopen("program.out","w",stdout); memset(f,255,sizeof(f)); while (~scanf("%d%d",&m,&n)) printf("%d\n",Solve(n+1,m)); return 0; }
相关文章推荐
- rqnoj-107-Ural的鹰蛋实验-dp
- 【DP】RQNOJ #107 Ural的鹰蛋实验
- RQNOJ 107 Ural的鹰蛋实验 解题报告
- RQNOJ107_鹰蛋实验
- URAL 1519 Formula 1 dp(插头)
- 概率dp ural 1776. Anniversary Firework
- Ural 1519. Formula 1 优美的插头DP
- ural 1057 Amount of degrees (数位dp)
- Ural 1519 Formula 1( 插头dp )
- URAL1009 - K-based Numbers - 数位dp
- 简单DP Stone Pile Ural_1005
- ural 1009. K-based Numbers - dp
- [ural1519]Formula 1 && 插头DP
- ural 1018 Binary Apple Tree(树形DP)
- 【URAL 1057】 Amount of Degrees 【数位DP】
- rqnoj 26 合唱队形(双向序列dp)
- URAL1119——DP——Metro
- URAL 1353. Milliard Vasya's Function(dp)
- URAL 1119 Metro (DP动态规划)
- URAL1002——DP——K-based Numbers. Version 2(未AC)