1. 程式人生 > >UVA12627-Erratic Expansion(遞歸)

UVA12627-Erratic Expansion(遞歸)

indicate all 個數 img i++ esp hat 返回 ret

Problem UVA12627-Erratic Expansion

Accept: 465 Submit: 2487
Time Limit: 3000 mSec

技術分享圖片 Problem Description

技術分享圖片

技術分享圖片 Input

The ?rst line of input is an integer T (T < 1000) that indicates the number of test cases. Each case contains 3 integers K, A and B. The meanings of these variables are mentioned above. K will be in the range [0,30] and 1 ≤ A ≤ B ≤ 2K.

技術分享圖片 Output

For each case, output the case number followed by the total number of red balloons in rows [A,B] after K-th hour.

技術分享圖片 Sample Input

3 0 1 1 3 1 8 3 3 7

技術分享圖片 Sample Output

Case 1: 1

Case 2: 27

Case 3: 14

題解:本來想找規律,但是純粹找規律不太好找,參考了一下lrj的思路,設g(k,i)為k小時後第i行及以下的紅氣球個數,這樣遞歸方程就很好推了(詳見代碼),紅氣球的個數很顯然是3^k,還有一個註意的點是,舉個例子,k=2,則此時最多4行,如果求第5行及以下的氣球數,直接返回0即可。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 typedef long long LL;
 5 
 6 const int maxn = 50;
 7 
 8 int k, a, b;
 9 int two_pow[maxn];
10 LL tri_pow[maxn];
11 
12 LL g(int k, int i) {
13     if (i > two_pow[k]) return 0LL;
14     if (k == 0) return 1LL;
15     if (i > two_pow[k - 1
]) { 16 return g(k - 1, i - two_pow[k - 1]); 17 } 18 else { 19 return 2 * g(k - 1, i) + tri_pow[k - 1]; 20 } 21 } 22 23 int main() 24 { 25 //freopen("input.txt", "r", stdin); 26 int iCase; 27 scanf("%d", &iCase); 28 two_pow[0] = 1; 29 tri_pow[0] = 1LL; 30 for (int i = 1; i <= 30; i++) { 31 two_pow[i] = two_pow[i - 1] * 2; 32 tri_pow[i] = tri_pow[i - 1] * 3; 33 } 34 35 int con = 1; 36 37 while (iCase--) { 38 scanf("%d%d%d", &k, &a, &b); 39 printf("Case %d: %lld\n", con++, g(k, a) - g(k, b + 1)); 40 } 41 42 return 0; 43 }

UVA12627-Erratic Expansion(遞歸)