eden拯救大兵雷诺

题目名称

拯救大兵雷诺

题目描述

新晋的星灵大主教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,人类战败。

题目难度

0

题目解释

即求遍历所有m个点且不被打败的方案数,每一次能够到下一个点前提条件是该点没有被遍历过,同时目前剩余时间能够到达这一个点并且打败这一个点。

方法&解释

利用深搜回溯,第一次进入是第一个点0,当前的剩余的时间n,和当前经过的点数tot,先判断是否tot==m,如果tot达到m则说明此方案遍历了m个点,方案数++,回退到前一个点(前一个点继续循环改变后一个点),如果tot!=m则列举当前能够走的点1-m均可以作为下一个到达的点,只需要判断即可,如果b数组用来标记该点是否被走过,走过则标记为1如果没有走过则为0,判断是否走过,目前的方案没有走过该点则可以走,另一个判断是否能够在剩余时间内打败该点,如果两个条件均满足则能够走该点,于是走该点,b[j]标记为1,走的点数加一,tot++,继续往下走,进入子程序(那么j即为进入的点,时间也应该为开始的时间-a[i][j]-t[j]+c[j]);

每一次走每一步都可以在1-m之中选择,即下面的循环,当一个方案出了之后,回退到之前的(可以以栈来模拟演示一下)子程序,回溯即b[j]标记为0,tot--相当于将该步骤走的该点置为没有走过,其实这个方法和m*m层循环并没有什么区别,都是把全部的方案都遍历,只是在之前就判断了一点是否可以进入,而不是像循环一样全部都傻傻地进行了,而且其实循环还要每一层层判断比这个难写,每一次改变方案数都是从后向前,先是最后一个点改变,所有改变完之后,然后倒数第二个点改变,接着又进入最后一步,又最后一个点改变...大致循环过程是和循环一样的,可以按照循环的改变来理解。

我的代码

 1 #include<stdio.h>
 2 int m, b[12] = {0}, a[12][12] = {0}, t[12] = {0}, c[12] = {0}, num = 0;
 3 void does(int i, int n, int tot) {
 4     int j;
 5     if (tot == m) {//是否完成一个方案
 6         num++;
 7         return;//完成一个方案则返回
 8     }
 9     for (j = 1; j <= m; j++) {
10         if (b[j] == 0 && a[i][j] + t[j] < n) {//判断你目前要走的点是否可以走
11             b[j] = 1;
12             tot++;
13             does(j, n - a[i][j] - t[j] + c[j], tot);//走下一个点
14             b[j] = 0;//回溯
15             tot--;
16         }
17     }
18 }
19 int main() {
20     int n, i, j;
21     scanf("%d%d", &n, &m);
22     for (i = 1; i <= m; i++) {
23         scanf("%d", &t[i]);
24     }
25     for (i = 1; i <= m; i++) {
26         scanf("%d", &c[i]);
27     }
28     for (i = 0; i <= m; i++) {
29         for (j = 0; j <= m; j++) {
30             scanf("%d", &a[i][j]);
31         }
32     }
33     b[0] = 1;
34     does(0, n, 0);//从零点出发
35     printf("%d\n", num);
36 }

标程代码

 1 #include <stdio.h>
 2
 3 #define MAXm 11
 4
 5 typedef struct {
 6     int x, i, n;
 7 } str;
 8
 9 int main() {
10     int m, i, j, t = 0, ans = 0;
11     char visited[MAXm] = { 0 };
12     str stack[MAXm];
13     int A[MAXm][MAXm], T[MAXm], C[MAXm];
14     scanf("%d%d", &stack[0].n, &m);
15     for (i = 1; i <= m; ++i)
16         scanf("%d", T + i);
17     for (i = 1; i <= m; ++i)
18         scanf("%d", C + i);
19     for (i = 0; i <= m; ++i)
20         for (j = 0; j <= m; ++j)
21             scanf("%d", &A[i][j]);
22     stack[0].x = 0;
23     stack[0].i = 0;
24     while (t >= 0) {
25         if (t == m) {
26             ++ans;
27             visited[stack[t].x] = 0;
28             --t;
29         } else {
30             while (++stack[t].i <= m)
31                 if (A[stack[t].x][stack[t].i] + T[stack[t].i] < stack[t].n
32                     && !visited[stack[t].i]) {
33                     stack[t+1].i = 0;
34                     stack[t+1].x = stack[t].i;
35                     stack[t+1].n = stack[t].n - A[stack[t].x][stack[t].i]
36                         - T[stack[t].i] + C[stack[t].i];
37                     visited[stack[t++].i] = 1;
38                     break;
39                 }
40             if (stack[t].i > m)
41                 visited[stack[t--].x] = 0;
42         }
43     }
44     printf("%d\n", ans);
45     return 0;
46 }

标答解释

明天再写==

第一次写题解,希望以后可以坚持写下去,写的不好,大家见谅~

时间: 2024-10-23 04:20:46

eden拯救大兵雷诺的相关文章

【codevs 1911 孤岛营救问题】

·为了分析方便,可以先做一个题目简化.去掉"钥匙"这个条件,那么就是一个BFS或者SPFA--现在加上该条件.如本题只给出最多两种钥匙,当然你可以继续坚持BFS等方式,时间不会太差.但是一旦钥匙种类上升至15的时候,就有太多情况需要处理(光说你写BFS的if就是很长的过程,但个人认为时间复杂度依旧能过这道题). ·如图是简化版本的决策方式(为与后文呼应,用SPFA): 大方块是整个地图.小方块是一个房间.那么你可以在向四个方向走,前提是有路可走(没有墙).你本可以轻松拯救大兵瑞恩,然后

HTML学习笔记 CSS学习选择器 第五节 (原创)

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="tzy.css" type="text/css"> <style type="text/

HTML学习笔记 CSS学习选择器案例 第五节 (原创) 参考使用表

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="tzy.css" type="text/css"> <style type="tex

吐血推荐250部必看电影下载 IMDB TOP 250 download

中文名: IMDB Top 250合辑 TLF-MiniSD收藏版英文名: IMDB Top 250 TLF-MiniSD Collection版本: (更新至TOP119)[MiniSD]发行日期: 2010年地区: 美国语言: 英语 简介: IMDB Top 250合辑 TLF-MiniSD收藏版制作&发行:TLF HALFCD TeamTLF耗时2年精心打造,虎年开篇扛鼎之作 IMDB TOP 250邀您共赏一个世纪的经典 IMDB TOP250是IMDB网站里很受欢迎的特色栏目,里面列出

全球100部最佳影片排行

全球100部最佳影片排行 以下是IMDB(美国著名影评网站)网民评出全球100部最佳影片 :  1. <教父>The Godfather 1972年 8.9 分  科波拉黑帮经典<教父>的首部,派拉蒙公司最成功的影片之一,坐稳IMDB头把交椅应属,众望所归.虽然评论界一致对<教父>系列的第2集推崇有佳,但大多数影迷似乎还是对<教父>情有独钟,这可能与马龙·白兰度极具个力的表演有关,直到今天他那种含 糊沙哑的声音与神秘莫测的表情都依然叫人着迷.  2. <

Python开发简单爬虫之静态网页抓取篇:爬取“豆瓣电影 Top 250”电影数据

目标:爬取豆瓣电影TOP250的所有电影名称,网址为:https://movie.douban.com/top250 1)确定目标网站的请求头: 打开目标网站,在网页空白处点击鼠标右键,选择"检查".(小编使用的是谷歌浏览器). 点击"network",在弹出页面若长时间没有数据显示,则试一下F5刷新. 可以得到目标网页中Host和User-Agent两项. 2)找到爬取目标数据(即电影名称)在页面中的位置 右键"检查",选择"Elem

常用模块一

一.什么是模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用python编写的代码(.py文件) 2 已被编译为共享库或DLL的C或C++扩展 3 包好一组模块的包 4 使用C编写并链接到python解释器的内置模块 为何要使用模块? 如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通

从巴铁看,非法集资毁掉创新后还有办法拯救吗?

近日,一桩引人注目的非法集资案成为媒体头条.北京公安局东城分局发布的消息显示,针对投资人举报北京华赢凯来资产管理有限公司从事非法集资活动的情况,东城分局依法立案侦查,先后将白志明等32名犯罪嫌疑人抓获归案.而这家涉案公司,正是秦皇岛"巴铁1号试验车"项目的出资公司. 原本"巴铁1号"是创新的代表案例,在此前引发诸多轰动.但让人没想到的是,最终却成为非法集资的一个噱头.而从长远来看,非法集资毁掉的不仅仅是"巴铁1号",更是投资者和大众对创新的信心.

拯救OIBH总部

拯救OIBH总部 area [题目描述]: OIBH总部突然被水淹没了!现在OIBH需要你的救援…… OIBH被突来的洪水淹没了>.<还好OIBH总部有在某些重要的地方起一些围墙,用*号表示,而一个封闭的*号区域洪水是进不去的……现在给出OIBH的围墙建设图,问OIBH总部没被淹到的重要区域(由"0"表示)有多少. [输入描述]: 第一行是两个数,x和y(x,y<=500) 第二行及以下是一个由*和0组成的x*y的图. [输出描述]: 输出没被水淹没的OIBH总部的“