求取出这些邮票的最大连续组合值。

有4种面值的邮票很多枚,这4种邮票面值分别1,4,12,21,现从多张中任取5张进行组合,求取出这些邮票的最大连续组合值。

http://blog.sina.com.cn/s/blog_5dc7bbf80100v77b.html

#include<stdio.h>

#define M 5

#define N 5

int k,Found,Flag[N];

int Stamp[M] = {0,1,4,12,21};

//在剩余张数n中组合出面值和Value

int Combine(int n,int Value)

{

    if(n >= 0 && Value == 0)

         {

             Found = 1;

             int Sum = 0;

             for(int i = 0; i < N && Flag[i] != 0;i++)

                  {

                       Sum += Stamp[Flag[i]];

                       printf("%d",Stamp[Flag[i]]);

                   }

                   printf("\tSum = %d\n\n",Sum);

          }

     else

         for(int i = 1; i < M && !Found && n > 0;i++)

              if(Value - Stamp[i] >= 0)

                   {

                           Flag[k++] = i;

                           Combine(n - 1,Value - Stamp[i]);

                           Flag[--k] = 0;

                    }

      return Found;

}

int main(int argc,char* argv[])

{

     for(int i = 1;Combine(N,i);i++,Found = 0);

}

 

// StampCombine.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include<stdio.h>
#define M 5
#define N 5
int k,Found,Flag[N];
int Stamp[M] = {0,1,4,12,21};

void printResult()
{
    int Sum = 0;
    for(int i = 0; i < N && Flag[i] != 0;i++)
    {
        printf("%d ",Stamp[Flag[i]]);
        Sum += Stamp[Flag[i]];
    }
    printf("\tSum = %d\n\n",Sum);
}

//在剩余张数n中组合出面值和Value
void Combine(int n,int Value)
{
    if(n >= 0 && Value == 0)//机会刚好用完,或还没用完(n >= 0),值已经凑足(Value == 0)
    {
        Found = 1;
        printResult();
        return;
    }
    else if (n<=0 && Value>0)//机会已经用完,值还没凑足
    {
        Found = 0;
        //printf("\n n = %d, Value=%d\n",n,Value);
        return;
    }
    else//(寻找之中...)机会还没用完,值也还没凑足
    {   // n>0 && Value>0
        for(int i = 1; i < M && !Found && n > 0;i++)
        {
            if(Value - Stamp[i] >= 0)
            {
                Flag[k] = i;//将Stamp[i]的索引i,记录于Flag[k]之中
                k+=1;//Flag的索引增一,为下一次存储做准备

                //进一步深入去找...
                Combine(n - 1,Value - Stamp[i]);//假如选中Stamp[i],则需利用剩余的(n - 1)个选择机会,凑足(Value - Stamp[i])

                //退一步(还原k、Flag[k]),回溯...
                k-=1;
                Flag[k] = 0;
            }
        }
        
    }

}

void main(int argc,char* argv[])
{
    int i;
    for(i = 1,Found = 0;;i++,Found = 0)
    {
        //
        printf("%d: ",i);
        Combine(N,i);
        if (Found == 0)
        {
            break;
        }
    }
}

 

posted @ 2018-03-23 14:24  sky20080101  阅读(273)  评论(0)    收藏  举报