拯救大兵雷诺(递归+回溯)

2024-02-02 10:58

本文主要是介绍拯救大兵雷诺(递归+回溯),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

新晋的星灵大主教Artanis在目睹了挚友Zeratul的牺牲之后决心对抗黑暗之神Amon。为此,他首先要团结全星区所有种族的力量。

坚定的盟友雷诺和他刚刚结束了Arcturus统治的Terran帝国正在遭受Amon控制的异虫的攻击,帮助他们即可在日后对抗Amon的时候获得帮助。

当星灵部队抵达时,人类的战线已经崩溃,Artanis预测,如果没有星灵的帮助,人类部队将在n单位时间之后彻底战败。异虫部队在战场上建立了m个据点,编号从1到m,要想帮助人类取得胜利,必须击破全部的m个据点。Artanis还预测出了击破第i个据点所需的时间Ti,同时,击破第i个据点会导致异虫的攻势减弱,人类战败的倒计时会增加Ci单位时间。此外,Artanis还计算出了星灵部队战场上任意两点间移动所需的时间Ai,j表示从第i个据点到第j个据点所需的单位时间,0 <= i, j <= m,0表示星灵部队的大本营。

由于Artanis作为大主教还是个新人,指挥能力还不足以发动多线作战,因此他只能从大本营出发,一个一个地摧毁异虫的据点。他现在想知道,在保证人类部队不全军覆没的前提下,有多少种不同的进攻顺序?

输入格式

输入包括m + 4行:

第1行包括2个整数:n和m

第2行包括m个整数:Ti

第3行包括m个整数:Ci

第4至m+4行(共m+1行)是一个(m+1) * (m+1)整数矩阵:Ai,j

整数之间使用空格分隔

输出格式

输出只包含1个整数,即不同的进攻顺序方案数

输出结尾应有一个换行符

数据规模:

0 < n <= 10000, 0 < m <= 10, 0 < Ti, Ci, Ai,j <= 1000

此外,由于星灵拥有诸多人类无法理解的高端技术,因此在据点之间移动所需的时间Ai,j不一定满足三角形不等式,即不保证满足Ai,j <= Ai,k + Ak,j,也不能保证Ai,j = Aj,i,但是Ai,i一定为0

样例输入:

5 3

1 2 3

3 2 1

0 1 1 1

1 0 1 1

1 1 0 1

1 1 1 0

样例输出:

2

样例解释:

只有1 2 3和2 1 3的进攻顺序才能保证倒计时始终在0以上

如果按照1 3 2的顺序来进攻的话,进攻1需要1+1 = 2的时间,还剩下3,又增加3变成6;接下来进攻3需要1+3=4的时间,还剩下2,又增加1变成3;最后进攻2需要1+2=3的时间,倒计时变成0,人类战败。

递归+回溯实际上就是遍历所有情况,如果能在当前情况下成功就继续往下走,如果不能就退出来,寻找下一个能实现当前情况的点。
所以在递归函数中要加一个存当前情况的参数

#include <stdio.h>
#include <string.h>
int n, m, t[10] = {0};
int c[10], b[12] = {0};
int a[1000][1000];
int sum = 0, tot;
void rescue(int i, int n, int tot) {int j;if (tot == m) {sum++;return;}b[i] = 1;//用来确定不能重复救同一个点,在不同的递归函数中,b【i】的值是不同的。for (j = 1; j <= m; j++) {if (b[j] == 0 && n - a[i][j] - t[j] > 0) {tot++;rescue(j, n - a[i][j] - t[j] + c[j], tot);b[j] = 0;tot--;}}return;
}
int main() {scanf("%d %d", &n, &m);for (int i = 1; i <= m; i++) {scanf("%d", &t[i]);}for (int i = 1; i <= m; i++) {scanf("%d", &c[i]);}for (int i = 0; i <= m; i++) {for (int j = 0; j <= m; j++) {scanf("%d", &a[i][j]);}}for (int i = 0; i <= m; i++) {tot = 0;rescue(i, n, tot);memset(b, 0, sizeof(b));}printf("%d\n", sum);return 0;
}

这篇关于拯救大兵雷诺(递归+回溯)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/670482

相关文章

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT

回溯——9.全排列

力扣题目链接 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: 输入: [1,2,3]输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 解题思路 问题建模:题目要求给出一个数组的所有排列组合,属于典型的全排列问题,这可以用回溯法来解决。回溯法通过递归的方式,依次将数组中的每个元素放入排列中,直到生成

oracle11.2g递归查询(树形结构查询)

转自: 一 二 简单语法介绍 一、树型表结构:节点ID 上级ID 节点名称二、公式: select 节点ID,节点名称,levelfrom 表connect by prior 节点ID=上级节点IDstart with 上级节点ID=节点值 oracle官网解说 开发人员:SQL 递归: 在 Oracle Database 11g 第 2 版中查询层次结构数据的快速

Leetcode面试经典150题-128.最长连续序列-递归版本另解

之前写过一篇这个题的,但是可能代码比较复杂,这回来个简洁版的,这个是递归版本 可以看看之前的版本,两个版本面试用哪个都保过 解法都在代码里,不懂就留言或者私信 class Solution {/**对于之前的解法,我现在提供一共更优的解,但是这种可能会比较难懂一些(思想方面)代码其实是很简洁的,总体思想如下:不需要排序直接把所有数放入map,map的key是当前数字,value是当前数开始的

风控系统之指标回溯,历史数据重跑

个人博客:无奈何杨(wnhyang) 个人语雀:wnhyang 共享语雀:在线知识共享 Github:wnhyang - Overview 回顾 默认你已经看过之前那篇风控系统指标计算/特征提取分析与实现01,Redis、Zset、模版方法。 其中已经介绍了如何利用redis的zset结构完成指标计算,为了方便这篇文章的介绍,还是在正式开始本篇之前回顾一下。 时间窗口 zset

【UVA】10651-Pebble Solitaire(直接递归或者记忆化)

不知道这个题UVA的数据是怎么的,用2个方法交了,第一次直接递归,第二次记忆化剪枝,时间竟然一样!? 直接郁闷了,简单的二进制表示状态和二进制运算。 14145176 10651 Pebble Solitaire Accepted C++ 0.009 2014-09-04 09:18:21 #include<cstdio>#include<algorithm>#inclu

165-Stamps【回溯】

回溯 给h和k的意思是在k种邮票中选h个邮票 基本的连续邮资问题 15226160 165 Stamps Accepted C++ 0.062 2015-03-27 07:21:37 #include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 2

笔试强训,[NOIP2002普及组]过河卒牛客.游游的水果大礼包牛客.买卖股票的最好时机(二)二叉树非递归前序遍历

目录 [NOIP2002普及组]过河卒 牛客.游游的水果大礼包 牛客.买卖股票的最好时机(二) 二叉树非递归前序遍历 [NOIP2002普及组]过河卒 题里面给的提示很有用,那个马的关系,后面就注意,dp需要作为long的类型。 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息publ

HCIA--实验十:路由的递归特性

递归路由的理解 一、实验内容 1.需求/要求: 使用4台路由器,在AR1和AR4上分别配置一个LOOPBACK接口,根据路由的递归特性,写一系列的静态路由实现让1.1.1.1和4.4.4.4的双向通信。 二、实验过程 1.拓扑图: 2.步骤: (下列命令行可以直接复制在ensp) 1.如拓扑图所示,配置各路由器的基本信息: 各接口的ip地址及子网掩码,给AR1和AR4分别配置

Winform中在窗体中的Paint事件中重绘会导致递归问题?

在 WinForms 应用程序中,如果在窗体的 Paint 事件处理程序中不断调用 Invalidate 方法,确实可能会导致递归调用的问题。这是因为每次调用 Invalidate 方法时,都会向消息队列添加一个绘制消息,当消息队列中的绘制消息被处理时,会触发 Paint 事件。如果 Paint 事件处理程序中又调用了 Invalidate,就会形成一个循环,导致递归调用 Paint 事件,这