首页 > 代码库 > Dropping water balloons (入门dp)

Dropping water balloons (入门dp)

2017-08-12 18:36:24

writer:pprp

最近刚刚接触动态规划,感觉状态的查找和转移自己很难想到,都是面向题解编程,但是一开始都是这样了,只有相信我可以独立自己解决动态规划这类问题;

题意:给你N个水球,M个楼

水球可能在某个楼层上释放就会破裂,问最少在几次内就可以得到水球破裂的临界楼层

如果次数大于63那就输出:More than 63 trials needed.

状态分析:

dp[i][j] : 表示在目前有i个水球,还有j次释放机会时最多可以测到第几层

状态转移:

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

分析:

  分为两个部分,

    如果当前这个水球破了:即dp[i-1][j-1]+1,怎么理解呢,就是现在由于水球破了,导致变成了i-1个水球,并且知道这层不是临界,所以可以将楼层数+1

    如果当前这个水球没有破:即p[i][j-1],就是这个水球没有破,但是次数还是要-1的

细节:k = min(k,63)如果水球数量k大于63而题目中说明不能超过63次,那么就直接取63

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

using namespace std;
long long  n;
int k;
const int maxn = 65;
long long dp[110][maxn];

void solve()
{
    memset(dp,0,sizeof(dp));
    for(int i = 1 ; i < 64 ; i++)
    {
         for(int j = 1 ; j < 64 ; j++)
        {
            dp[i][j] = dp[i-1][j-1]+1+dp[i][j-1];
        }
    }
}


int main()
{
    solve();
    while(cin >> k >> n&&k&&n)
    {
        k = min(63,k);
        bool flag = false;
        for(int i = 1 ; i <= 63 ; i ++)
        {
            if(dp[k][i] >= n)
            {
                cout << i << endl;
                flag = true;
                break;
            }
        }
        if(!flag)
            cout << "More than 63 trials needed."<<endl;
    }
    return 0;
}

 

Dropping water balloons (入门dp)