递归法之穷举搜索

前言

  本文在于复习“穷举搜索”之递归算法。

一、英文原文题目

  Write a program which reads a sequence A A A of n n n elements and an integer M M M, and outputs “yes” if you can make M M M by adding elements in A A A, otherwise “no”. You can use an element only once You are given the sequence A A A and q q q questions where each question contains M i M_i Mi.

二、中文题目翻译

  现有长度为 n n n的数列 A A A和正整数 M M M。请编写一个程序,判断 A A A中任意几个元素相加是否能得到 m m m A A A中每个元素只能使用 1 1 1次。

三、输入及输出样例

1.输入

   1 1 1行输入 n n n
  第 2 2 2行输入 A A A n n n个整数
  第 3 3 3行输入 q q q
  第 4 4 4行输入整数 M i M_i Mi

2.输出

  输出个问题的答案,如果 A A A中元素相加能得到 m i m_i mi,则回答yes;反之,回答no.

3.示例

inputoutput
5no
1 5 7 10 21no
4yes
2 4 17 8yes

四、递归分割问题

  代码片段如下,其中关键部分为递归结束条件

bool solve(int i, int m) {
    //递归结束条件
    if(m == 0) return true;
    if(i >= n) return false;

    bool res = solve(i + 1, m) || solve(i + 1, m - A[i]);//第i个选或不选
    return res;
}

  具体迭代关系如下图所示,solve(i,m)i代表递归深度(从0开始),而m代表下一次的迭代的目标值。
递归分割问题
  我们在最后得到solve(i,0)即为成功。

五、完整代码

#include<stdio.h>

int n, A[50];

//从输入值M中减去所选元素的递归函数
bool solve(int i, int m) {
    //递归结束条件
    if(m == 0) return true;
    if(i >= n) return false;

    bool res = solve(i + 1, m) || solve(i + 1, m - A[i]);//第i个选或不选
    return res;
}

int main() {
    int q, M, i;
    scanf("%d", &n);//高效输入函数
    for(i = 0; i < n; i++) scanf("%d", &A[i]);

    scanf("%d", &q);
    for(i = 0; i < q; i++) {
        //输入一个判断一个
        scanf("%d", &M);
        if(solve(0, M)) printf("yes\n");
        else printf("no\n");
    }
    return 0;
}

六、后记

  第一次写博客,对于markdown一无所知,有诸多不适,望海涵。
  如有建议也可在直接评论区留言。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值