[uva 10934] Dropping water balloons
阿新 • • 發佈:2018-12-17
題意:n層樓樓房,有K個水球,每個水球都有一個相同的扛摔係數。即從某層樓高及其以下的樓層摔下不會壞,而從其以上的樓層摔下會壞。問:最少需要多少次嘗試能夠求得扛摔係數
更簡單的抽象:現在有一個未知數X,範圍在1-n內。現在需要猜至少多少次Y,返回的結果是Y<X或Y>X或Y=X,則可以求出X
我們定義dp[i]為:猜測 i 次後能夠得到的最大區間
那麼有如下幾種情況:
A:第 i 次返回Y<X,這種情況對dp[i]的貢獻為:dp[i-1]
B:第 i 次返回Y>X,這種情況對dp[i]的貢獻為:dp[i-1]
C:第 i 次返回Y=X,這種情況對dp[i]的貢獻為:1
所以,dp[i] = 2 * dp[i-1] + 1
根據上述,定義dp[i][j]為猜測 i 次,得到 j 次 Y>X 回答後遊戲結束時,能夠得到的最大區間
即有:dp[i][j] = dp[i-1][j] + dp[i-1][j-1] + 1
要求的答案為:dp[i][k] >= n中的最小的 i
一開始覺得可能會有精度問題:如果在某個加法過程中越界long long會怎麼樣,又沒法知道那麼大資料的結果是否正確,但是樣例有兩個這種大資料避免了這個想法
#include <iostream> #include <cstdio> #include <algorithm> #include <string.h> #include <cstdlib> using namespace std; long long n,dp[150][150]; int main() { int i,j,k; while(scanf("%d%lld",&k,&n)&&k){ memset(dp,0,sizeof(dp)); int flag=0; for(i=1;i<=63;i++){ for(j=1;j<=k;j++) dp[i][j]=dp[i-1][j]+dp[i-1][j-1]+1; if (dp[i][k]>=n){ flag=1; break; } } if (flag) printf("%d\n",i); else puts("More than 63 trials needed."); } return 0; }