以动归例题为载体的路径输出

我觉得,输出路径的话,首先需要一个结构体。
在结构体中,包括当前状态的一些想要的结果(如本例中代表钱币数目的变量ncoin),还应该包含上一个状态是 怎么变成当前状态的一个变量(下面简称改变变量->自创词汇),(比如本例子中的past_coin,这个变量的意思就是上一个状态是通过拿了一个面值为多少的钱币变成的当前状态),改变变量的出现告诉试图用回溯的方式找到输出路径的程序,它应该以哪种方式回溯到当时过来时的路径,因为当初这个变量就是储存上一个情况的信息,这么一说就有点像链表了(类似双向链表的前项指针)(因为动归嘛,最终结果是移动过来的。但是,在移动的途中可能会有多种不同的方式均可以使中间结果移动到同一个节点上,这是,就需要改变变量来告诉程序怎么找到当时的路径了,,,)
代码实现的是 给出总钱数,问最少要多少张钱币可以凑出这些钱,并且,输出这些钱币都是什么
#include <iostream>
#include <cstdio>
#define inf 0x3f3f3f3f
using namespace std;

struct Sum
{
    int ncoin;
    int past_coin;
};
Sum sum[100];

int main()
{
    int coin[6]={1,5,10,20,50,100};
    int total=73;//这里以total为例
    int temp=0;
    sum[0].ncoin=0;//现在一共有多少个硬币
    sum[0].past_coin=0;//上一个情况到现在的一个情况花费的硬币金额
    for(int i=1;i<=total;i++)
    {
        sum[i].ncoin=inf;
    }
    for(int i=1;i<=total;i++)//动归嘛,所以得从一开始的起始点,即总钱数为1的情况挪到总钱数为total的情况
    {
        for(int j=0;j<6;j++)
        {
            if(i-coin[j]>=0&&sum[i].ncoin>sum[i-coin[j]].ncoin+1)
            {
                sum[i].ncoin=sum[i-coin[j]].ncoin+1;
                sum[i].past_coin=coin[j];
            }
        }
    }
    printf("%d\n",sum[total].ncoin);
    temp=total;
    while(temp!=0)
    {
        printf("%d    ",sum[temp].past_coin);
        temp=temp-sum[temp].past_coin;
    }
    return 0;
}


 
 


猜你喜欢

转载自blog.csdn.net/qq_41764621/article/details/80806563