UVa12627 Erratic Expansion (分治)

链接:http://vjudge.net/problem/UVA-12627

分析:看图找规律,然后推式子。我们用f(k,i)表示k小时之后前i行红气球总数(i从1开始数)。容易看出k小时后,图分成四块,右下部分是没有红气球的,其它三部分相同。因此容易得到,

当i>(1<<(k-1))的时候,上半部分红气球总数为c(k-1)*2,下半部分红气球总数为f(k-1,i-(1<<(k-1))),所以总的红气球总数为c(k-1)*2+f(k-1,i-(1<<(k-1)))个;当i<=(1<<(k-1))时,此时的k小时后前i行红气球总数相当于k-1小时后,前i行红气球总数的两倍f(k-1,i)*2,边界条件是先检查f(k,0)=0然后检查f(0,i)=1。

 1 #include <cstdio>
 2
 3 int k, a, b;
 4 long long c[35];
 5
 6 long long f(int k, int i) {
 7     if (!i) return 0;
 8     if (!k) return 1;
 9     if (i <= (1<<(k-1))) return f(k-1, i) * 2;
10     if (i > (1<<(k-1))) return 2 * c[k-1] + f(k-1, i-(1<<(k-1)));
11 }
12
13 int main() {
14     c[0] = 1;
15     for (int i = 1; i < 30; i++) c[i] = c[i-1] * 3;
16     int T;
17     scanf("%d", &T);
18     for (int kase = 1; kase <= T; kase++) {
19         printf("Case %d: ", kase);
20         scanf("%d%d%d", &k, &a, &b);
21         long long ans = f(k, b) - f(k, a-1);
22         printf("%lld\n", ans);
23     }
24     return 0;
25 }
时间: 2024-10-11 04:57:46

UVa12627 Erratic Expansion (分治)的相关文章

uva 12627 - Erratic Expansion(递归求解)

递归的边界条件写的多了--没必要写呢么多的.. 不明白可共同探讨~ #include<cstdio> #include<iostream> #include<cmath> using namespace std; long long dp(int kk,int pos) { int n=kk;int temp=(int)pow(2,n); // printf("%d %d\n",kk,pos); if(kk==0&&pos==1) r

UVA - 12627 Erratic Expansion 奇怪的气球膨胀 (分治)

紫书例题p245 Piotr found a magical box in heaven. Its magic power is that if you place any red balloon inside it then, after one hour, it will multiply to form 3 red and 1 blue colored balloons. Then in the next hour, each of the red balloons will multip

8-12 Erratic Expansion uva12627

题意:一开始有一个红气球  每小时后一个红气球会变成三个红气球和一个蓝气球  第k小时 a到b行之间有几个红气球 递归找规律题目 一定要注意涉及指数的时候一定要开long long 数组!!!! #include<bits/stdc++.h> using namespace std; long long s[35]; long long f(int k,int i) { if(i<=0)return 0; if(k==0)return 1; if( i<=pow(2,k-1) )

UVA - 12627 Erratic Expansion(奇怪的气球膨胀)(递归)

题意:问k小时后,第A~B行一共有多少个红气球. 分析:观察图可发现,k小时后,图中最下面cur行的红气球个数满足下式: (1)当cur <= POW[k - 1]时, dfs(k, cur) = dfs(k - 1, cur); (2)当cur > POW[k - 1]时, dfs(k - 1, cur) = 2 * dfs(k - 1, cur - POW[k - 1]) + tot[k - 1]; 其中,POW[k - 1]为2^(k  - 1),tot[k - 1]为k-1小时后图中的

Uva 12627 Erratic Expansion(递归)

这道题大体意思是利用一种递归规则生成不同的气球,问在某两行之间有多少个红气球. 我拿到这个题,一开始想的是递归求解,但在如何递归求解的思路上我的方法是错误的.在研读了例题上给出的提示后豁然开朗(顺便吐槽一下算法竞赛第二版在这这道题目上(P246)提示写的有问题,g(k,i)=2g(k-1,i-2^(k-1))+c(k-1)  ,他把c(k-1)写成了c(k)...我纠结这个纠结了好久) 根据题目提示,这道题可以用f(k,i)表示k小时后最上边i行的红气球总数 那么我们的答案就可以表示为f(k,b

UVA 12627 Erratic Expansion

#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1<<29; ll k,a,b; ll s[maxn]; ll f(ll i,ll k) { if(i==0) r

(白书训练计划)UVa 12627 Erratic Expansion(递归+找规律)

题目地址:UVa 12627 这题是先找规律,规律在于对于第k个小时的来说,总是可以分成右下角全是蓝色气球,右上角,左下角与左上角三个一模一样的k-1个小时的气球.这样的话,规律就很清晰了,然后用递归做比较方便... 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <ma

(记忆化+暴力)UVA - 12627 Erratic Expansion

题意:一个数列,一开始只有一个1,进行k次操作,每次操作都把数列中原本的数全都翻倍然后追加在数列的后面,形成了一个全新的数列,输出全新数列中l到r的和. 分析:以上的题意是经过转化后的题意,变的非常简单,而不在卡在二维的思维中出不来. 可以看到如果在后半段,就等于前半段对应位置的两倍,可以从最高2^k个数的维护,k不断-1,最终变成维护数列中第一个1,直接返回1即可,形成了一个完美的递归. 1 ll dg(int u ,int d,int k) { 2 if(u==1&&d==1)retu

UVA 12673 Erratic Expansion 奇怪的气球膨胀

不难发现,每过一个小时,除了右下方的气球全都是蓝色以外,其他都和上一个小时的气球是一样的,所以是可以递推的.然后定义一类似个前缀和的东西f(k,i)表示k小时之后上面i行的红气球数.预处理出k小时的红气球总数c(k),递归时候注意终止条件. #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 31; ll c[maxn]; ll f(int k,int i) { if(!i) r