Poj--3783(DP)
2014-12-05 20:43:57
思路:一开始YY了B=2的情况,很容易发现规律,但B!=2的情况就不那么好想了,所以想到了DP。
那么考虑:因为50和1000都是很小的数,适合放进dp维度,如果dp[i][j]表示i个球j层楼需要的最少drops次数,那么转移方程:dp[i][j] = min(dp[i - 1][k] + dp[i][n - k])(0<k<n)运算量高达50*1000*1000,不符合。
换个思路:用dp[i][j]表示用i个球,j次drops次数所能测出的最大楼高,转移方程:dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 1] + 1,初始化:dp[i][0] = 0,运算量:50 * 50,然后预先打个表即可。
1 /************************************************************************* 2 > File Name: 3783.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Fri 05 Dec 2014 12:46:26 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 27 int T,tag,B,M; 28 int dp[60][60]; 29 30 void Pre(){ 31 for(int i = 0; i <= 50; ++i){ 32 dp[i][0] = 0; 33 } 34 for(int i = 1; i <= 50; ++i){ 35 for(int j = 1; j <= 50; ++j){ 36 dp[i][j] = max(dp[i][j],dp[i][j - 1] + dp[i - 1][j - 1] + 1); 37 } 38 } 39 } 40 41 int main(){ 42 Pre(); 43 scanf("%d",&T); 44 while(T--){ 45 scanf("%d%d%d",&tag,&B,&M); 46 int ans = 0; 47 for(int i = 1; i <= 1000; ++i){ 48 if(dp[B][i] >= M){ 49 ans = i; 50 break; 51 } 52 } 53 printf("%d %d\n",tag,ans); 54 } 55 return 0; 56 }