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; }
时间: 2024-09-29 20:07:53