这是比较难的一道题目,要解决问题首先要摸清楚F,D,B之间的数学规律,这确实比较难并且不好描述,我想了很久才想出来,我觉得如果要求在一个小时内搞定还真是非常不容易,至少如果是我的话如果无法灵光一现的话还真是想不出来……。 首先尝试最简单的递归方法,但是深度太大以致于连小测试数据都无法搞定,只能用递推,F,D,B <= 100 范围内可以构造一个101×101的二维数组并递推填充,可以很快得到结果,但是测试大测试数据的时候问题就出现了,不可能构造一个map并执行(2亿×2亿)次运算,只能对原来的算法进行优化,优化的前提要对数据的分布有更清楚的把握。 题目:
Problem
Imagine that you are in a building with F floors (starting at floor 1, the lowest floor), and you have a large number of identical eggs, each in its own identical protective container. For each floor in the building, you want to know whether or not an egg dropped from that floor will break. If an egg breaks when dropped from floor i, then all eggs are guaranteed to break when dropped from any floor j ≥ i. Likewise, if an egg doesn't break when dropped from floor i, then all eggs are guaranteed to never break when dropped from any floor j ≤ i.
We can define Solvable(F, D, B) to be true if and only if there exists an algorithm to determine whether or not an egg will break when dropped from any floor of a building with F floors, with the following restrictions: you may drop a maximum of D eggs (one at a time, from any floors of your choosing), and you may break a maximum of B eggs. You can assume you have at least D eggs in your possession.
Input
The first line of input gives the number of cases, N. N test cases follow. Each case is a line formatted as:
F D B
Solvable(F, D, B) is guaranteed to be true for all input cases.
Output
For each test case, output one line containing "Case #x: " followed by three space-separated integers: Fmax, Dmin, and Bmin. The definitions are as follows:
* Fmax is defined as the largest value of F' such that Solvable(F', D, B) is true, or -1 if this value would be greater than or equal to 232 (4294967296).
(In other words, Fmax = -1 if and only if Solvable(232, D, B) is true.)
* Dmin is defined as the smallest value of D' such that Solvable(F, D', B) is true.
* Bmin is defined as the smallest value of B' such that Solvable(F, D, B') is true.
Limits
1 ≤ N ≤ 100.
Small dataset
1 ≤ F ≤ 100,
1 ≤ D ≤ 100,
1 ≤ B ≤ 100.
Large dataset
1 ≤ F ≤ 2000000000,
1 ≤ D ≤ 2000000000,
1 ≤ B ≤ 2000000000.
Sample
Input
Output
2
3 3 3
7 5 3
Case #1: 7 2 1
Case #2: 25 3 2
下面贴代码
#pragma warning(disable:4786)
#include <iostream>
#include <vector>
#include <fstream>
#define max(a,b) ((a)<(b)?(b):(a))
#define all(a) a.begin(),a.end()
using namespace std;
typedef unsigned long ul32;
#define MAXU32 4294967295
#define BOVER2(a,b) (MAXU32 - b < a)
#define BOVER3(a,b,c) (BOVER2(a,b)? true:BOVER2(a+b,c))
// 小数据使用
#define EAGE 101
ul32 maxf_matrix[EAGE][EAGE] = {0};
// large matrix
// 大数据使用
vector< vector<ul32> > matrix;
// 递归方法,无法使用
ul32 max_f(ul32 D, ul32 B)
{
if (D == 0 || B == 0) return 0;
// if (D == 1 || B == 1) return 1;
return max_f(D-1,B) + max_f(D-1,B-1) + 1;
}
// 小数据构造矩阵
void constract_maxf()
{
for (int Y = 1; Y < EAGE; Y++)
for (int X = 1; X < EAGE; X++)
{
if ((X>1)&&(Y>1))
if ((maxf_matrix[Y][X-1] == 0) || (maxf_matrix[Y-1][X-1] == 0))
break;
if (BOVER3(maxf_matrix[Y][X-1], maxf_matrix[Y-1][X-1], 1))
continue;
maxf_matrix[Y][X] = maxf_matrix[Y][X-1] + maxf_matrix[Y-1][X-1] + 1;
}
}
ul32 get_max_d(ul32 F, ul32 B)
{
ul32 i = 1;
while (1)
{
if ((maxf_matrix[B][i] >= F) || (0 == maxf_matrix[B][i]))
return i;
i++;
}
}
ul32 get_max_b(ul32 F, ul32 D)
{
ul32 i = 1;
while (1)
{
if ((maxf_matrix[i][D] >= F) || (0 == maxf_matrix[i][D]))
return i;
i++;
}
}
// constract the large data matrix
// 全数据构造矩阵
void constract_large()
{
vector<ul32> line;
// line 0 4294967295
matrix.push_back( vector<ul32>(1,0) );
// line 1 4294967295
// 第一行可以得知关系为f(n)=n,不构造,可节省t>10秒的运行时间
matrix.push_back( vector<ul32>(1,0) );
// 构造第2行,以便后续递推构造3-n行
ul32 K = 0;
ul32 p = 0;
line.clear();
line.push_back(0);
while (1)
{
if (BOVER3(line[p], p, 1))
break;
//if (MAXU32 - p - 1 < line[p])
// break;
K = line[p] + p + 1;
line.push_back(K);
++p;
}
matrix.push_back(line);
// line 3 to line 32,
// 可以确定32行之后的行与32行数据相同,因为matrix[32][32] = 2^32-1,所以可以确定32为最优值
for (int x = 3; x<=32; x++)
{
K = 0;
p = 0;
line.clear();
line.push_back(0);
while(1)
{
// if (MAXU32 - p - 1 < line[p])
ul32 last = (matrix[x-1])[p];
if ((last == 0) && (p != 0))
break;
if (BOVER3(line[p], last, 1))
break;
K = line[p] + last + 1;
line.push_back(K);
++p;
}
int ui = line.size();
matrix.push_back(line);
}
}
ul32 large_maxf(ul32 D,ul32 B)
{
if (B == 1) return D;
if (B > 32) B = 32;
int i = matrix[B].size();
if (D >= matrix[B].size())
return 0;
return matrix[B][D];
}
ul32 large_maxd(ul32 F,ul32 B)
{
if (B > 32) B = 32;
ul32 p = 1;
if (B == 1)
return F;
ul32 len = matrix[B].size();
while (p < len)
{
if (matrix[B][p] >= F)
break;
++p;
}
return p;
}
ul32 large_maxb(ul32 F,ul32 D)
{
if (F <= D) return 1;
for (ul32 i = 2; i<=32; i++)
{
ul32 maxlen = matrix[i].size();
if (D > maxlen)
return i;
if (matrix[i][D] >= F)
return i;
}
return i;
}
int main(int *argc, char *argv[])
{
ifstream infile("C-large.in");
ofstream cout("C-large.out");
// freopen("A-small.in", "r", stdin);
int N = 0;
infile >> N;
int I = 1;
constract_maxf();
constract_large();
while (N-- > 0)
{
ul32 F,D,B;
infile >> F >> D >> B;
ul32 maxf = 0;
ul32 maxd;
ul32 maxb;
// maxf = max_f( D, B);
#if 0
maxf = maxf_matrix[B][D];
maxd = get_max_d(F, B);
maxb = get_max_b(F, D);
#else
maxf = large_maxf(D, B);
maxd = large_maxd(F, B);
maxb = large_maxb(F, D);
#endif
if (maxf == 0)
cout << "Case #" << I << ": " << "-1" << " " << maxd << " " << maxb << endl;
else
cout << "Case #" << I << ": " << maxf << " " << maxd << " " << maxb << endl;
I++;
}
return 0;
}