1060 勇者斗恶龙 (bfs, 剪枝)

Description

有一头有着N个头的恶龙,有M名骑士,每名骑士有一把魔剑。每一把魔剑有两个参数ci和di。如果当前恶龙的头不小于ci个,则骑士可以使用魔剑砍掉恶龙的恰好ci个头;如果当前恶龙的头小于ci个,则骑士无法使用这把魔剑;如果恶龙还没有死亡(即恶龙的头的个数大于0),则恶龙会立即长出di个头;如果恶龙的头的个数超过L个,则多余的头会脱落,并保持在L个;只有砍掉恶龙所有的头才算是杀死恶龙。 
你的任务就是判断这M个骑士能否杀死恶龙,如果可以,请输出最少需要使用魔剑的次数,否则输出“-1”。 

Input

输入数据的第一行是三个整数N,M,L(1≤N≤500,1≤M≤10,N≤L≤N+500),表示恶龙有N个头,骑士数目为M,恶龙的头的数量限制为L。紧接着M行,第i行有两个整数ci,di(0≤ci,di≤1,000,1≤i≤M),表示第i把魔剑的参数。如果能够杀死恶龙,则输出最少需要使用魔剑的次数,否则输出“-1”。每把魔剑的使用次数是无限的。

Output

输出一行一个整数B,表示能够杀死恶龙时最少需要使用魔剑的次数,如果不能杀死恶龙,输出-1

Sample Input

20 2 500
7 1
8 5

Sample Output

3

思路是:

 bfs暴力+剪枝判断能否杀死。(如果没砍死加上d[i],已经出现过,就不用加入到队列里了)

具体用代码解释比较清晰。

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
int n, m, L;
int c[1005], d[1005], vis[1005]; 
struct node{
	int num, t;
	node(int _num = 0, int _t = 0) : num(_num), t(_t) {}
};
int bfs(){
	queue<node> q;
    memset(vis, 0, sizeof(vis)); 
	node now, next;
	q.push(node(n, 0));
	vis[n] = 1;
	while(!q.empty()) {
		  now = q.front();
		  q.pop();
		  for(int i = 1; i <= m; i++) {
		   	 if(now.num == c[i]) return now.t + 1;
			 if(now.num > c[i]) {
				  next.num = min(now.num - c[i] + d[i], L);
				  next.t = now.t + 1;
				 if(vis[next.num] == 0) {
			 	 	 vis[next.num] = 1;
			 		 q.push(next);
			 	 } 
			 } 
		  }
	}
	return -1;
}
int main(void) {
	while(cin >> n >> m >> L) {
		for(int i = 1; i <= m; i++) {
			cin >> c[i] >> d[i];
		}	
		cout << bfs() << endl;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值