递归之dfs Exchange Cards

本文介绍了一个基于篮球卡片价值和数量的交换算法问题。该算法帮助计算玩家如何利用手中不同价值的卡片来等价交换目标卡片的方法数。输入包括目标卡片价值、玩家拥有的卡片种类及其价值和数量,输出为可行的交换方案总数。

Exchange Cards

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 13   Accepted Submission(s) : 10
Problem Description
As a basketball fan, Mike is also fond of collecting basketball player cards. But as a student, he can not always get the money to buy new cards, so sometimes he will exchange with his friends for cards he likes. Of course, different cards have different value, and Mike must use cards he owns to get the new one. For example, to get a card of value 10$, he can use two 5$ cards or three 3$ cards plus one 1$ card, depending on the kinds of cards he have and the number of each kind of card. And Sometimes he will involve unfortunately in a bad condition that he has not got the exact value of the card he is looking for (fans always exchange cards for equivalent value).

Here comes the problem, given the card value he plans to get and the cards he has, Mike wants to fix how many ways he can get it. So it's you task to write a program to figure it out.

Input

The problem consists of multiple test cases, terminated by EOF. There's a blank line between two inputs.

The first line of each test case gives n, the value of the card Mike plans to get andm, the number of different kinds of cards Mike has. n will be an integer number between 1 and 1000.m will be an integer number between 1 and 10.

The next m lines give the information of different kinds of cards Mike have. Each line contains two integers,val and num, representing the value of this kind of card, and the number of this kind of card Mike have.

Note: different kinds of cards will have different value, eachval and num will be an integer greater than zero.

Output

For each test case, output in one line the number of different ways Mike could exchange for the card he wants. You can be sure that the output will fall into an integer value.

Output a blank line between two test cases.

Sample Input

5 2
2 1
3 1

10 5
10 2
7 2
5 3
2 2
1 5

Sample Output

1

7

 

Source
Zhejiang University Local Contest 2006
#include<cstdio>
#include<cstring>
using namespace std;

int n,m;

struct card
{
    int val;
    int num;
}p[15];

int cnt;

void dfs(int cur,int total,int tar)
{
    if(total==tar)
    {
        cnt++;
        return;
    }
    if(total>tar||cur==m)
    return;
    for(int i=0;i<=p[cur].num;i++)
    dfs(cur+1,total+i*p[cur].val,tar);
}

int main()
{
    bool flag=false;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(flag)
        printf("\n");
        for(int i=0;i<m;i++)
        scanf("%d%d",&p[i].val,&p[i].num);
        cnt=0;
        dfs(0,0,n);
        printf("%d\n",cnt);
        flag=true;
    }
    return 0;
}

### 非递归深度优先搜索(DFS)算法实现 非递归深度优先搜索(DFS)可以通过显式使用栈来实现。与递归版本不同,非递归版本需要手动管理栈以模拟函数调用的过程。以下是基于栈的非递归 DFS 算法的详细说明和代码示例。 在非递归 DFS 中,栈用于存储待访问的节点[^4]。每次从栈中弹出一个节点并标记为已访问,然后将其未访问的邻接节点压入栈中。此过程重复进行,直到栈为空为止。 以下是使用 Python 实现的非递归 DFS 示例: ```python def dfs_iterative(graph, start): visited = set() # 记录已访问的节点 stack = [start] # 初始化栈,将起始节点压入栈 while stack: # 当栈不为空时继续循环 vertex = stack.pop() # 弹出栈顶元素 if vertex not in visited: # 如果节点未被访问 visited.add(vertex) # 标记为已访问 print(vertex, end=" ") # 输出当前节点(可替换为其他操作) # 将当前节点的所有未访问邻居压入栈 stack.extend(reversed([node for node in graph[vertex] if node not in visited])) ``` #### 示例输入和输出 假设图的邻接表表示如下: ```python graph = { 'A': ['B', 'C'], 'B': ['A', 'D', 'E'], 'C': ['A', 'F'], 'D': ['B'], 'E': ['B', 'F'], 'F': ['C', 'E'] } dfs_iterative(graph, 'A') ``` 输出结果可能为(取决于图结构和邻接节点的顺序): ``` A C F E B D ``` #### 关键点解析 1. **栈的作用**:栈用于保存当前路径上的节点,模拟递归调用的过程。 2. **访问顺序**:每次从栈中弹出一个节点,并将其未访问的邻接节点按逆序压入栈中,以确保正确的访问顺序[^3]。 3. **终止条件**:当栈为空时,表示所有可达节点均已访问完毕[^4]。 ### 注意事项 - 在实现过程中,必须确保对每个节点进行访问标记,避免重复访问导致无限循环[^1]。 - 邻接节点的压栈顺序会影响遍历结果,通常建议按逆序压栈以保持与递归版本一致的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值