以下是来自spoj的问题的实现: - http://www.spoj.com/problems/COINS/
#include <stdio.h>
#define ll long long
ll arr[100000];
ll max(ll n)
{
if(n < 49999)// Doubt
{
if(!arr[n])
return arr[n] = max(n/2) + max(n/3) + max(n/4);
else
return arr[n];
}
else
return max(n/2) + max(n/4) + max(n/3);
}
int main()
{
ll n, c = 0, i;
for(i = 0; i < 12; i++) // Also why 12 when the input can be <12
{
arr[i] = i;
}
while(scanf("%lld", &n) != EOF)
{
printf("%lld\n", max(n));
}
return 0;
}
为什么if条件包含n&lt; 49999?
答案 0 :(得分:2)
没有检查每种可能性,除了前20个值以及最大值和最小值之外:
我的期望是
预先计算arr []中的前12个条目以帮助减少递归的深度,但是美元值与前12个条目的计算值不同。
对于硬币值&lt; = 49999,检查是否已经计算了值,如果没有,则将硬币分成/ 2/3/4值并递归每个结果值。
此限制值(49999)可以扩展到100000,因为它是arr []数组的可用大小。
预设和保存到arr []数组有助于减少执行时间和递归深度。
使用数组是因为任何先前计算的值(在发布的代码中,最多49999)都可以由max()
函数立即返回,而无需进一步递归。
我会稍微修改代码,以获得更好的文档和健壮性以及更快的执行速度,如下所示:
#include <stdio.h>
#include <stdint.h>
#define MAX_ARRAY_LEN (100000)
uint32_t arr[ MAX_ARRAY_LEN ] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
uint32_t max(uint32_t n)
{
if(n < MAX_ARRAY_LEN)
{ // value of 'n' within the range of the learning array arr[]
if(!arr[n] && n)
{ // then learning array arr[] not yet set
return arr[n] = max(n/2) + max(n/3) + max(n/4);
}
else
{ // else learning array arr[] already set for 'this' value of 'n'
return arr[n];
}
}
else
{ // value of 'n' is greater than the learning array arr[]
return max(n/2) + max(n/4) + max(n/3);
}
} // end function: max
int main( void )
{
uint32_t n;
int status;
while( (status = scanf("%u", &n)) == 1 && EOF != status)
{
if( 1000000000 >= n)
{
printf("%u\n", max(n) );
}
else
{
printf(" invalid value entered, must be in the range 0...1 000 000 000\n");
} // end if
} // end while
return 0;
} // end function: main
答案 1 :(得分:0)
据我了解,
编写代码的人,不知怎的,他发现(手动)if 硬币少于12然后结果将是自己。所以他用12 (检查输入硬币的解释= 2)
关于递归函数
正如我们所知,我们无法宣布大小为1,000,000,000的数组,所以他试图这样做 使用一些其他值(这里是49999),他可以在其中创建数组的大小 然后像arr [12] = 13那样将数据的结果取为数组 (其中12是硬币,结果是13),这样他就能得到结果 通过使用带有arr [12]的数组而不生成值(仅) 硬币12。
希望你明白。