UVA 12627(遞推&遞歸_H題)解題報告
阿新 • • 發佈:2018-01-25
get tdi 圖片 mat ble log gpo b- lin
同理,我們也可以利用g(k,i)表示k小時後最下邊i行的紅氣球總數,將答案用g(k,i)表示出來。
題目鏈接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4352
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
題意:氣球按照一定方式進行復制,要求給出數量。
思路:
根據題目提示,這道題可以用f(k,i)表示k小時後最上邊i行的紅氣球總數那麽我們的答案就可以表示為f(k,b)-f(k,a-1)這裏我們通過觀察,在k小時後所分成的四部分氣球中,最右下角區域的氣球是跟其他區域氣球不相同的。因此我們可以分成兩種情況(i在上半部分和i在下半部分):
當i<2^(k-1),f(k,i)=2*f(k-1,i)
當i>=2^(k-1),f(k,i)=c(k-1)+f(k-1,i-2^(k-1))
其中c(k-1)代表完整的那部分的紅氣球數,也就是k-1小時後的紅氣球數。
由氣球構造方式可得遞推式:c(k)=3c(k-1),c(0)=1,可知這是個等比數列,求得c(k)=3^k。
代碼:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<string> #include<vector> #include<stack> #include<bitset> #include<cstdlib> #include<cmath> #include<setView Code> #include<list> #include<deque> #include<map> #include<queue> using namespace std; typedef long long ll; const double PI = acos(-1.0); const double eps = 1e-6; ll c[30]={1}; ll ballon(ll K,ll i){ if(i<=0) return 0; if(K==0) return 1; if(i<=pow(2,K-1)) return 2*ballon(K-1,i); else return 2*c[K-1]+ballon(K-1,i-pow(2,K-1)); } int main(void){ for(int p=1;p<=30;p++){ c[p]=c[p-1]*3; } int T=0; scanf("%d",&T); int count =1; //freopen("out.txt","wa",stdout); for(int i=0;i<T;i++){ ll K,A,B; scanf("%lld %lld %lld",&K,&A,&B); printf("Case %d: %lld\n",count,ballon(K,B)-ballon(K,A-1)); count++; } return 0; }
UVA 12627(遞推&遞歸_H題)解題報告