1-2-5组合问题的最高效完整算法
问题描述:用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;
- }