您的位置:首页 > 其它

1-2-5组合问题的最高效完整算法

2010-01-17 16:11 309 查看
问题描述:用1,2,5这三个数组合,和为N。1,2,5的个数自己定,求有多少种不同的组合方法?

/************************************************************************
***By       : Summon                                                  ***
***Data     : 2010.01.17                                              ***
***Function : 1-2-5组合之和等于100,文总共有多少种                           ***
***           组合方式。                                                      ***
***Method   : 首先使用蛮力发,复杂度O(n^3/)                              ***
***           其次使用蛮力法的改进,复杂度O(n^2)                          ***
***           最后是超级算法,复杂度O(n)                            ***
/************************************************************************/
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

typedef int STATUS;

STATUS FoolHardinessMethod(int N, int *result);
STATUS FoolHardinessMethodImproved(int N, int *result);
STATUS SuperMethod(int N, int *result);

int main(int argc, char* argv[])
{
clock_t start;
clock_t end;
double realTime;
int N;

printf("Please input the N!/n");
fflush(stdin);
scanf("%d", &N);

int result = 0;
start = clock();
FoolHardinessMethod(N, &result);
end = clock();
realTime = ((double)(end - start))/CLOCKS_PER_SEC;
printf("N= %d/n", N);
printf("FoolHardinessMethod Running Time = %f/n", realTime);
printf("result = %d/n", result);
printf("/n");

start = clock();
FoolHardinessMethodImproved(N, &result);
end = clock();
realTime = ((double)(end - start))/CLOCKS_PER_SEC;
printf("N= %d/n", N);
printf("FoolHardinessMethodImproved Running Time = %f/n", realTime);
printf("result = %d/n", result);
printf("/n");

start = clock();
SuperMethod(N, &result);
end = clock();
realTime = ((double)(end - start))/CLOCKS_PER_SEC;
printf("N= %d/n", N);
printf("SuperMethod Running Time = %f/n", realTime);
printf("result = %d/n", result);
printf("/n");

return 1;
}

STATUS FoolHardinessMethod(int N, int *result)
{
if (result == NULL)
{
return 0;
}

int N1 = N/1;
int N2 = N/2;
int N5 = N/5;
*result = 0;

for (int i=0; i<=N5; i++)
{
for (int j=0; j<=N2; j++)
{
for (int k=0; k<=N1; k++)
{
if (5*i + 2*j + k == N)
{
*result += 1;
}
}
}
}
return 1;
}

STATUS FoolHardinessMethodImproved(int N, int *result)
{
if (result == NULL)
{
return 0;
}

int N2 = N/2;
int N5 = N/5;
*result = 0;

for (int i=0; i<=N5; i++)
{
for (int j=0; j<=N2; j++)
{
if (((N - 5*i - 2*j) >= 0) && ((N - 5*i - 2*j) <= N))
{
*result += 1;
}
}
}
return 1;
}

STATUS SuperMethod(int N, int *result)
{
if (result == NULL)
{
return 0;
}

*result = 0;

for (int i=0; i<=N; i+=5)
{
*result += (i+2)/2;
}

switch (N%5)
{
case 0:
{
break;
}
case 1:
{
*result += (1*(N - N%5))/10;
break;
}
case 2:
{
*result += (2*(N - N%5))/10 + 1;
break;
}
case 3:
{
*result += (3*(N - N%5))/10 + 1;
break;
}
case 4:
{
*result += (4*(N - N%5))/10 + 2;
break;
}
}
return 1;
}


其中第三种算法的思路参考:http://blog.csdn.net/sailor_8318/archive/2008/10/22/3120812.aspx

但是以上博客中提到的方法仅仅适用于N能够被5整除时,本算法进一步解决了N为任意正整数时的情况。

总体的思路就是利用N与(N - N%5)之间的关系。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: