一道递归算法的时间复杂度计算

liangqikang 2011-08-18 10:09:46
小弟对递归算法的时间复杂度的计算总是把握不准,比如下边这道,时间复杂度应该怎么计算呢?有劳高人指教。


#include <iostream>
using namespace std;

int scores[10];
int sum;

void output()
{
for (int i=0; i<10; ++i) {
cout << scores[i] << ", ";
}
cout << endl;
sum ++;
}

void shoot(int num, int score)
{
if (score < 0 || score > (num + 1) * 10) {
return;
}
if (num == 0) {
scores[num] = score;
output();
return;
}
for (int i=0; i<=10; ++i) {
scores[num] = i;
shoot(num - 1, score - i);
}
}

int main (int argc, char * const argv[]) {
shoot(9, 90);
cout << "总数: " << sum << endl;
return 0;
}

...全文
399 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
kenyyy 2011-08-24
  • 打赏
  • 举报
回复
你这个复杂度计算不对的吧?你这程序最后打印的结果就要比你计算出的大了吧?你的程序里面每一层是相乘的

[Quote=引用 11 楼 liangqikang 的回复:]
引用 10 楼 kenyyy 的回复:

忘记所了,复杂度的话就是9*90,相信你自己也会算吧?


存下来?要注意是有顺序的啊,每一轮的shoot(a, b),都是不一样的。


考察一下递归树的话,大概是这样的:

T(9, 90)

T(8, 89) T(8, 88) ... T(8, 80)

T(7, 79) T(7, 78) ... T(7, 70……
[/Quote]
kenyyy 2011-08-24
  • 打赏
  • 举报
回复
int shoot(int num, int score)
{
int num = 0;
if (score < 0 || score > (num + 1) * 10) {
return 0;
}
if (num == 0) {
scores[num] = score;
output();
return 1;
}
if (0 != res[num][score])
return res[num][score];
for (int i=0; i<=10; ++i) {
scores[num] = i;
num += shoot(num - 1, score - i);
}
res[num][score] = num;
return num;
}

大概改了下,原先没怎么看清楚,原来你没有返回总数的,还打印了结果。。。。这么弄结果是没法打印的

liangqikang 2011-08-23
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 kenyyy 的回复:]

忘记所了,复杂度的话就是9*90,相信你自己也会算吧?
[/Quote]

存下来?要注意是有顺序的啊,每一轮的shoot(a, b),都是不一样的。


考察一下递归树的话,大概是这样的:

T(9, 90)

T(8, 89) T(8, 88) ... T(8, 80)

T(7, 79) T(7, 78) ... T(7, 70)

T(6, 69) T(6, 68) ... T(6, 60)
.
.
.
T(0, 9) T(0, 8) ... T(0, 0)
最后一层时间都用在输出上了,t = 10 * 10 = 100
逐步往上,每一层的时间是:t = 11 * 2 + 底层的时间
由此看来复杂度应该是O(100 + 11 * 2 * 8) = O(276)
kenyyy 2011-08-23
  • 打赏
  • 举报
回复
忘记所了,复杂度的话就是9*90,相信你自己也会算吧?
kenyyy 2011-08-23
  • 打赏
  • 举报
回复
一个简单而有效的改动。 你每次计算出shoot(a,b)的值,把结果保存下来,下一次需要计算shoot(a,b)时,可以直接返回结果,不需要再全部计算了。

[Quote=引用 5 楼 liangqikang 的回复:]
引用 4 楼 kenyyy 的回复:

好烂的递归。。。。


兄台有更好的劳烦拿出来分享下啊
[/Quote]
kjs008 2011-08-21
  • 打赏
  • 举报
回复
看不懂楼主的递归为什么在外面还有加个for循环,下面的计算方法不知道是否正确。

楼主可以验证下, 如果num+1比num慢很多,则很可能就是下面的指数数量级的复杂度

T(n) = 10T(n-1) + O(1) ==>10^n

假设 T(n) = O(10^n) => T(n)<=c10^n - k
则: T(n) <= 10*(10^n-1 - k) + k
= 10^n - 9k
<=10^n - k

所以 T(n) = O(10^n)



liangqikang 2011-08-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 nuptxxp 的回复:]

感觉lz的递归会有很多重叠的子结构,试试用dp可能好一点
lz这个递归应该是这样的吧:T(n)=T(n-1)+T(n-2)+......+T(1)+O(n);
这个分析感觉有点麻烦
还有LZ的程序使用诸如10这样的数,最好使用变量代替,适用于各种情况(说实话,没看懂LZ程序想干嘛)
[/Quote]

Sorry,是我没有说明清楚。
要解决的问题是:士兵打靶,靶有1到10环对应1到10分;要计算连续打10次,总分拿到90分有多少种可能情况?
要求用递归的方法。

给出的解法看起来确实不怎么好看;递归的变量是有两个的。。。

各位还有更好的解法否?
kenyyy 2011-08-19
  • 打赏
  • 举报
回复
好烂的递归。。。。
nuptxxp 2011-08-19
  • 打赏
  • 举报
回复
感觉lz的递归会有很多重叠的子结构,试试用dp可能好一点
lz这个递归应该是这样的吧:T(n)=T(n-1)+T(n-2)+......+T(1)+O(n);
这个分析感觉有点麻烦
还有LZ的程序使用诸如10这样的数,最好使用变量代替,适用于各种情况(说实话,没看懂LZ程序想干嘛)
liangqikang 2011-08-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 kenyyy 的回复:]

好烂的递归。。。。
[/Quote]

兄台有更好的劳烦拿出来分享下啊
phoenix_share 2011-08-19
  • 打赏
  • 举报
回复
每层的运算次数之和即为时间复杂度,很明显,这道题每层的运算次数是10的倍数,也就是以10为公比的等比数列,深度为num,那么时间复杂度就是O(10^num).
liangqikang 2011-08-18
  • 打赏
  • 举报
回复
具体的思路?
感觉应该没有这么小吧。。

zuoguodang 2011-08-18
  • 打赏
  • 举报
回复
O(logN)?

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧