这道题大体意思是利用一种递归规则生成不同的气球,问在某两行之间有多少个红气球。

我拿到这个题,一开始想的是递归求解,但在如何递归求解的思路上我的方法是错误的。在研读了例题上给出的提示后豁然开朗(顺便吐槽一下算法竞赛第二版在这这道题目上(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)-f(k,a-1)

如何求f(k,i)?

这里我们通过观察,在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

至此我们就可以得到我们想要的答案了。

同理,我们也可以利用g(k,i)表示k小时后最下边i行的红气球总数,把我们的答案用g(k,i)表示出来,这里不再叙述。

以下是完整代码:

 #include <cstdio>
using namespace std;
long long c(int k){
long long sum = ;
while(k--)sum*=;
return sum;
}
long long g(int k, int i) {
if(i == ) return ;
if(k == ) return ; int k2 = << (k-);
if(i >= k2) return *g(k-, i-k2) + c(k-);
else return g(k-,i);
}
long long f(int k,int i){
if(i==)return ;//注意这两处边界的处理
if(k==)return ;
int t = << (k-);
if(i<t)return *f(k-,i);
else return *c(k-) + f(k-,i-t);
}
int main(){
int T, k, a, b;
scanf("%d",&T);
for(int kase = ; kase <= T; kase++) {
scanf("%d%d%d",&k,&a,&b);
printf("Case %d: %lld\n",kase,f(k, b) - f(k, a-));
//int t =1 << k;
//printf("Case %d: %lld\n",kase,g(k, t-a+1) - g(k,t- b));
}
return ;
}
 long long c(int i) { return i ==  ?  : c(i-)*; }

另外代码仓库中c的求法比较简洁,值得学习。

Uva 12627 Erratic Expansion(递归)的更多相关文章

  1. uva 12627 - Erratic Expansion(递归求解)

    递归的边界条件写的多了--不是必需写呢么多的.. 不明确可共同探讨~ #include<cstdio> #include<iostream> #include<cmath ...

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

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

  3. UVa 12627 Erratic Expansion - 分治

    因为不好复制题目,就出给出链接吧: Vjudge传送门[here] UVa传送门[here] 请仔细看原题上的那幅图,你会发现,在时间t(t > 0),当前的气球构成的一幅图,它是由三个时间为( ...

  4. UVA 12627 - Erratic Expansion

    一个红球能够分裂为3个红球和一个蓝球. 一个蓝球能够分裂为4个蓝球. 分裂过程下图所看到的: 设当前状态为k1.下一状态为k2. k1的第x行红球个数 * 2 ⇒ k2第2*x行的红球个数. k1的第 ...

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

    紫书例题p245 Piotr found a magical box in heaven. Its magic power is that if you place any red balloon i ...

  6. 12627 - Erratic Expansion——[递归]

    Piotr found a magical box in heaven. Its magic power is that if you place any red balloon inside it ...

  7. UVA 12673 Erratic Expansion 奇怪的气球膨胀 (递推)

    不难发现,每过一个小时,除了右下方的气球全都是蓝色以外,其他都和上一个小时的气球是一样的,所以是可以递推的.然后定义一类似个前缀和的东西f(k,i)表示k小时之后上面i行的红气球数.预处理出k小时的红 ...

  8. 【数形结合】Erratic Expansion

    [UVa12627]Erratic Expansion 算法入门经典第8章8-12(P245) 题目大意:起初有一个红球,每一次红球会分成三红一蓝,蓝球会分成四蓝(如图顺序),问K时的时候A~B行中有 ...

  9. UVa 12627 (递归 计数 找规律) Erratic Expansion

    直接说几个比较明显的规律吧. k个小时以后,红气球的个数为3k. 单独观察一行: 令f(r, k)为k个小时后第r行红气球的个数. 如果r为奇数,f(r, k) = f((r+1)/2, k-1) * ...

随机推荐

  1. JVM垃圾回收补充知识点

    1. 分代 虚拟机中的共划分为三个代: 年轻代(Young Gen):eden和survivor-8:1:1 年老代(Old Gen):存储大对象,由survivor晋升 永久代(perm Gen): ...

  2. 微信小程序全局/页面配置

    flex布局 父元素 display:flex; flex-direction: row; justify-content:space-between 补充 flex-direction属性决定主轴的 ...

  3. js如何判断数据类型

    1.最常见的判断方法:typeof console.log(typeof a) ------------> string console.log(typeof b) ------------&g ...

  4. Git push提示pre-receive hook declined

    master:local auto@ubuntu:~/src/code/ git push Counting objects: 5, done. Delta compression using up ...

  5. Super Reduced String

    https://www.hackerrank.com/challenges/reduced-string/problem He wants to reduce the string to its sh ...

  6. Tornado异步之-协程与回调

    回调处理异步请求 回调 callback 处理异步官方例子 # 导入所需库 from tornado.httpclient import AsyncHTTPClient def asynchronou ...

  7. ThinkPHP框架介绍

    什么是框架 php框架是许多代码的集合,这些代码的程序结构的代码(并不是业务代码)代码中有许多的函数,类,功能类包 不使用框架开发的缺陷 代码编写不规范 牵一发而动全身 不能很好满足客户各方面的需求 ...

  8. 微信小程序播放视频

    <view class="section tc"> <video id="myVideo" src="http://wxsnsdy. ...

  9. clear()、sync()、ignore()

    #include <iostream> using namespace std; int main() { int a; cin>>a; cout<<cin.rds ...

  10. TreeMap与LinkedHashMap的区别

    TreeMap是根据元素的内部比较器进行排序的,它可以根据key值的大小排序: LinkedHashMap是保持存放顺序的. TreeMap采用红黑树算法,遍历效率高: LinkedHashMap采用 ...