29
习习习习 习习习习 ()

习题选 讲(分治法)

  • Upload
    maisie

  • View
    95

  • Download
    15

Embed Size (px)

DESCRIPTION

习题选 讲(分治法). 递归与分 治. Rate of Return Binary Tree sicily 1935. 二叉树重建 电路 稳定性 Monthly Expense Pie sicily 1028. Hanoi Tower Sequence 1211 商人的宣传 1071 Floors. 1017 Rate of Return. 解题思路: 当利润率在 [0,1] 之间,假设投资额和时间不变,则利润率越高,最后的本金和利润总和越大。 - PowerPoint PPT Presentation

Citation preview

Page 1: 习题选 讲(分治法)

习题选讲(分治法)

Page 2: 习题选 讲(分治法)

2

递归与分治 Rate of Return Binary Tree sicily 1935. 二叉树重建 电路稳定性 Monthly Expense Pie sicily 1028. Hanoi Tower Sequence 1211 商人的宣传 1071 Floors

Page 3: 习题选 讲(分治法)

3 2011-10-20

1017 Rate of Return

解题思路:当利润率在 [0,1]之间,假设投资额和时间不变,则利润率越高,最后的本金和利润总和越大。

因此对利润率进行二分查找,检查在假设的利润率下,比较最后的本金和利润总和与实际值,调整二分上下界,直到达到某个精度。

Page 4: 习题选 讲(分治法)

4 2011-10-20

1017 Rate of Return double find(double left,double right,int m,double x) { double center,s=0; center=(left+right)/2; if (right-left<=0.000000005) return center; for (int i=1;i<=m;i++) s+=a[i]*pow(1.0+center,m+1-i); if (s<x) return find(center,right,m,x); else return find(left,center,m,x); }

Page 5: 习题选 讲(分治法)

5

Binary Tree Given a binary tree, every node of which

contains one upper case character (‘A’ to ‘Z’); you just need to print all characters of this tree in pre-order.

Input: 4 C 1 0表示标志符为 4的点,点值为C,其左儿子为标识符为 1的点,没有右孩子。3 4 C 1 3 1 A 0 0 3 B 0 0

Output: CAB2011-12-21

Page 6: 习题选 讲(分治法)

6

二叉树重建题目大意:输入一棵二叉树的先序遍历序列和中序遍历序列,输出它的广度优先遍历序列。

例如,先序 ABCDEF,中序 CBAEDF

Page 7: 习题选 讲(分治法)

7

二叉树重建解题思路前序遍历,根节点最先被输出,所以 A是根结点。中序遍历,左子树的全部结点输出后,接着输出根结点,最后输出右子树的全部结点。

例如,先序 ABCDEF,中序 CBAEDFA

BCDE F

Page 8: 习题选 讲(分治法)

8

二叉树重建左子树:前序 BC,中序 CB右子树:前序 DEF,中序 EDF

A

BCDE F

A

B

C

DE F

A

B

C

D

E F

Page 9: 习题选 讲(分治法)

9

二叉树重建void build(int n, int dep, char* s1, char* s2){ if (n <= 0) return; int p = strchr(s2, s1[0]) - s2; lv[dep][ln[dep]++] = s1[0]; build(p, dep+1, s1+1, s2); build(n-p-1, dep+1, s1+p+1, s2+p+1);}

调用: build(strlen(s1), 0, s1, s2);

Page 10: 习题选 讲(分治法)

10

电路稳定性题目大意:给出一个电路,以及各元件断路的概率。求整个电路断路的概率。

Page 11: 习题选 讲(分治法)

11

电路稳定性 解题思路: n个元件,若它们的断路概率为 p1,p2,...,pn,则串联断路概率为 1-(1-p1)(1-p2)...(1-pn),并联断路概率为 p1p2...pn。

问题的关键点是把字符串表示的电路转化为实际电路。

http://222.200.182.58/viewsource.php?sid=87438

Page 12: 习题选 讲(分治法)

12

Monthly Expense

题目大意:农夫知道未来 N天每天的花费,他现在需要把这 N天分成连续的M段,使得花费最大的段花费最小。求这个花费。

1 <= N <= 100,000, 1 <= M <= N

Page 13: 习题选 讲(分治法)

13

Monthly Expense

解题思路:二分最高花费,再使用贪心的方法求出在这个花费下是否能把 N天分成M段且每段都不超过这个花费,从而调整二分的上下界。

Page 14: 习题选 讲(分治法)

14

Monthly Expense while(min<=max){ mid=(min+max)/2; int t=0;int num=0; for(i=0;i<n;i++){ if(num+N[i]<=mid)num+=N[i]; else {t++; if(t>m)break; num=N[i];} } if(num)t++; if(t<=m){ ans=mid; max=mid-1; } else min=mid+1; }

Page 15: 习题选 讲(分治法)

15

Pie

题目大意:一共有 N个派和 F+1个人,每个人分到一份派,要求每个人分到的派的大小相等,问最大的面积是多少。

1 ≤ N, F ≤ 10 000

Page 16: 习题选 讲(分治法)

16

Pie

解题思路:二分派的大小,再使用贪心的方法求出在这个大小下,是否足够分给所有人,从而调整二分的上下界。

Page 17: 习题选 讲(分治法)

17

Pie

while(max-min>1e-5){ mid=(min+max)/2.0; int sum=0; for(i=0;i<n;i++) sum+=(int)(N[i]/mid); if(sum<f) max=mid; else min=mid; }

Page 18: 习题选 讲(分治法)

18 2011-10-20

1028 Hanoi Tower Sequence

题目大意:定义汉诺塔,共有三个柱子和很多的大小两两不同的盘子放在一个柱子上,要求把它们移到另一个柱子上,每次只能移动一个放在柱子最顶端的盘子,并且每次移动后需保证较小的盘子在较大的盘子上面。给出步数 p,求第 p步移动的盘子的大小。

p<=10^100

Page 19: 习题选 讲(分治法)

19 2011-10-20

1028 Hanoi Tower Sequence

解题思路: n个盘子的汉诺塔问题递归求解:把前 n-1个盘子移到第二根柱子上,把第 n个盘子移到第三根柱子上,把前 n-1个盘子移到第三根柱子上。

从一根柱子到另一根柱子,移动 1个盘子需要f(1)=1步,移动 k(k>1)个盘子需要 f(k)=f(k-1)+1+f(k-1)步。

即得到 f(k)=2^k-1。因此第 2^k步移动的是 k+1个盘子。在移动第 k+1个盘子后,左右对移地移动 k个盘子。

Page 20: 习题选 讲(分治法)

20 2011-10-20

1028 Hanoi Tower Sequence

把 p化成二进制数,假设现在 p里有超过1个位为 1,设最高位为 k,则在 2^k步前和 2^k步后对称,因此第 p步移的盘子与第 p-2^k步移的盘子一样。

直到 p里只有 1个位为 1,设此时p=2^m,则此步移动的是第m+1个盘子。

因此题目转化成二进制数 p,从低位起连续 0的位数,加 1,为答案。

Page 21: 习题选 讲(分治法)

21 2011-10-20

1028 Hanoi Tower Sequence

int cal(int a[],int n) { int cnt=1; while (a[n-1]%2==0) { cnt++; for (int i=0,temp=0;i<n;i++) { temp=temp*10+a[i]; a[i]=temp/2; temp%=2; } } return cnt; }

Page 22: 习题选 讲(分治法)

22 2011-10-20

1211 商人的宣传题目大意:有 n个州,m条单向边,规定天数为 L。共有 q个询问,每个询问为从州 A到州 B刚好为 L步的方案数。

Page 23: 习题选 讲(分治法)

23 2011-10-20

1211 商人的宣传解题思路:第 0天,每个州到自己的方案数为 1。第 n+1天,每个州 A到另一个州 B的方案数为,对所有州 C,第 n天从 A到 C的方案数与一天内从 C到 B的方案数的积,再对所有州求和。(即第 n天通过州 C作中转的方案)

Page 24: 习题选 讲(分治法)

24 2011-10-20

1211 商人的宣传 int cal(int A,int B) { int i,j,k; memset(ans,0,sizeof(ans)); ans[0][A][A]=1; for (k=1;k<=L;k++) { for (i=1;i<=n;i++) for (j=1;j<=n;j++) ans[k][A][i]+=ans[k-1][A][j]*edge[j][i]; return ans[L][A][B]; }

Page 25: 习题选 讲(分治法)

25 2011-10-20

1071 Floors

题目大意:一块长方形地板是由很多长方形瓷砖组成的,每次可以从中选一块,沿着瓷砖的边缘按直线切成两块,直到没有任何块可以继续此操作。求出此时最大的块的面积。

Page 26: 习题选 讲(分治法)

26 2011-10-20

1071 Floors

解题思路:对于每一块,尝试平行于长方形的两边分别切割。对于分出来的小块,递归进行重复操作。

判断是否可切割:按垂直于切割方向对瓷砖进行排序,切割线所切出来的块的面积与所在一侧的瓷砖总面积之和相等,则可切割。

Page 27: 习题选 讲(分治法)

27 2011-10-20

1071 Floors

void cal(int x1,int y1,int x2,int y2,int l,int r) { int s=(x2-x1)*(y2-y1); if (s<=ans) return; if (cutx(x1,y1,x2,y2,l,r)) return; if (cuty(x1,y1,x2,y2,l,r)) return; if (s>ans) ans=s; }

Page 28: 习题选 讲(分治法)

28 2011-10-20

1071 Floors bool cmpx(const rect &a,const rect &b) { return

a.xl<b.xl; } bool cutx(int x1,int y1,int x2,int y2,int l,int r) { sort(a+l,a+r+1,cmpx); int x=x1,s=0; for (i=l;i<r;i++) { s+=a[i].s; if (a[i].xh>x) x=a[i].xh; if (s==(x-x1)*(y2-y1)) { cal(x1,y1,x,y2,l,i); cal(x,y1,x2,y2,i+1,r); return true; } } return false; }

Page 29: 习题选 讲(分治法)

29

谢谢!