1223. Chernobyl’ Eagle on a Roof

http://acm.timus.ru/problem.aspx?space=1&num=1223

DP  神一般的维度转换

最简单的想法就是  dp[ i ][ j ]  i 个蛋 j 层楼 最少需要多少次试验

如果只有一个 蛋 则需要试验 j 次  否则:

dp[ i ][ j ] =min( dp[ i ][ j ] , max ( dp[ i ][ j-w] , dp[ i-1] [ w-1]) ) ;  ( w<=j&&w>=1 ) (w 表示开始选择哪个楼层)

虽然这样很好理解 但是 需要枚举 w 所以时间复杂度可以达到 1000^3  太高

我们可以想象 在蛋的个数确定的情况下 一定的楼层数对应的最少试验次数  的求解

可以等同于    在蛋的个数确定的情况下 一定的试验次数对应的可以达到的最高楼层 问题的求解

ans[ i ][ j ] 表示 i 个蛋 j 次 试验最多可以测试的楼层数

这时我们就不需要枚举开始时测试哪个楼层了  因为

假设我们开始需要选择 第w个楼层才最优 则它下面有 ans[ i-1 ][ j-1] 个楼层 上面有ans[ i ][ j-1 ]个楼层

ans[ i ][ j ]=ans[ i-1 ][ j-1] + ans[ i ][ j-1 ] + 1; 

并不要问选择了哪个楼层  其实 w 的值是可以通过  ans[ i ][ j-1 ] 来确定的 只不过没有必要而已

代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <queue>

#include <vector>

#include <algorithm>



#define LL long long

//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const int N=1005;

int ans[N][N];

int main()

{

    //freopen("data.txt","r",stdin);

    for(int i=1;i<N;++i)

    ans[1][i]=i;

    for(int i=2;i<N;++i)

    {

        for(int j=1;j<N;++j)

        {

            ans[i][j]=ans[i-1][j-1]+ans[i][j-1]+1;

        }

    }

    int n,m;

    while(scanf("%d %d",&n,&m)!=EOF)

    {

        if(!n&&!m)

        break;

        for(int i=1;i<N;++i)

        {

            if(ans[n][i]>=m)

            {printf("%d\n",i);break;}

        }

    }

    return 0;

}



 

 

 

你可能感兴趣的:(OO)