OJ之路(第一天)

经过一夜难以入眠的煎熬,我戴着熊猫眼滚下床,打开电脑,想着昨天那道做不出的题目,心里有所不甘。于是,有了今天。

今天,我一打开电脑,进入oj系统,看着题目,信心满满。于是,有了以下的总结:

①这是一支开启我训练之门的钥匙:

=================================================================================================================

题目描述如下:

有N个士兵站成一队列, 现在需要选择几个士兵派去侦察。为了选择合适的士兵, 多次进行如下操作: 如果队列超过三个士兵, 那么去除掉所有站立位置为奇数的士兵, 或者是去除掉所有站立位置为偶数的士兵。直到不超过三个战士,他们将被送去侦察。现要求统计按这样的方法,总共可能有多少种不同的正好三个士兵去侦察的士兵组合方案。
注: 按上法得到少于三士兵的情况不统计。1 <= N <= 2的32次方-1
输入格式
有多行,每行一个数字N,最后一行是0
输出格式
对每一行的数字N,输出针对N的方案数
直到没有数字
输入样例
10
4
0
输出样例
2
0

=================================================================================================================

思考过程:

这里是奇数分一半,偶数分一半,那么我们可以这样思考:

“等价转换”思想:实际上这种做法等同于分左右两半。

“递归“思想:你想一下,分成两半后,又是同样的问题(即继续分两半)--所谓的子问题,一直到不能或者不需要再分为止。

=================================================================================================================

细节上引发的问题:

以上思考形成的算法会带来一个问题:如果数据过大,那么该程序的运行时间是难以接受的。

解决方法:

”记忆搜索“思想:当数据很大的时候,你会容易发现”数据小的部分“已经重复计算了很多次了,所以这种思想就是"把重复计算很多次的结果给储存起来,等到以后

处理时遇到相同的问题,我们就可以直接拿结果来用,而不用再重复计算“。

其实”记忆搜索“这种思想在很多方面都有体现(特别是在递归上的应用):求高次幂运算(例如:2的100次方),fibnacci数列的非递归求法,给范围求素数个数etc。

=================================================================================================================

源代码:

#include <stdio.h>
//传说中的记忆搜索,能够解决一些超时问题(出现多次重复计算)
int record[10000];			
int DealWith(int m, int n)
{
	int tmp = n - m + 1;
	if (tmp < 10000 && record[tmp] != -1)
		return record[tmp];
	else if ( tmp < 3)
		return 0;
	else if ( tmp == 3)
		return 1;
	else {
		int ct = DealWith(m, m + tmp / 2 - 1) + DealWith(m + tmp / 2, n);
		if ( tmp < 10000 )
			record[tmp] = ct;
		return ct;
	}
}
int main()
{
	for (int i = 0; i < 10000; ++i)
		record[i] = -1;
	int n;
	while ( scanf( "%d", &n ) && n != 0 ) {
		printf("%d\n", DealWith( 1, n ) );
	}
	return 0;
}

=================================================================================================================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值