「TJOJ1110」菜哭武读论文

题目描述

新格尔公司的天才程序员刚刚接了一个特别厉害的项目,所以他最近正在阅读论文找灵感。菜哭武有一个习惯就是每天给自己定一个小目标,不完成这个小目标不睡觉。

读论文期间,他把自己找到的相关的论文都编了号从1 号到1,000号,每天读一部分。

比如说今天的任务就是从编号a读到b的论文。但是今天菜哭武的心情不大好,所以他不想每一篇都读,所以他准备准备阅读编号为 a和 b的以及其中的一部分论文,并且阅读顺序有些要求,如果他读完了编号为 i的论文,那么他下一篇可以选择阅读编号为  i-2,,i+2,或者 i*2三者中的任意一篇(当然了,编号不在[1,1,000] 范围内的论文他是不会看的,但是他有可能会去看编号在[a, b]之外的论文),菜哭武读论文的速度非常快,可以忽略,但是读两篇论文之间他需要休息,休息的时间取决于他下一篇选取了哪篇论文,如果选择编号为 i*2的,那么需要休息 x分钟;如果选择编号为 i+2的 需要休息 y分钟 ;如果选择了 i-2的需要休息 z分钟。那么他想知道今天按照他的方式从 a编号的论文开始读,直到读完 b编号的论文,最少需要多少分钟。

天才程序员菜哭武自然是会算的,但是他最近心情不好呀,不想算,所以需要你帮帮忙。

输入

题目包含多组数据。

输入的第一行有一个整数 T (1≤T≤10) 代表有 T组数据。

对于每组数据分为两行:

第一行有两个整数 a,b (1≤a,b≤1,000)。

第二行有三个整数 x,y,z (1≤x,y,z≤1,000)。

输出

对于每组数据,输出的第一行为 Case #x: ,其中 x是数据编号(从1开始),

第二行,有一个整数,最少花的时间,如果永远不可能达到小目标,输出-1。

样例输入

4
1 19
1 1 1
4 7
1 2 3
4 8
100 1 1
4 10
2 100 3

样例输出

Case #1:
9
Case #2:
-1
Case #3:
2
Case #4:
10

题解

把1-1000当成点,休息时间当成边权,跑最短路就行了。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream> 
#include <cstdio> 
#include <cmath> 
#include <cstring> 
using namespace std;

int s, t, u, x, y, z;
int w[1001][1001], dis[1001];
bool pd[1001][1001], used[1001];
int main()
{
	freopen("a.txt", "r", stdin);
	cin >> u;
	for (int pp = 1; pp <= u; pp++)
	{
		memset(w, 0, sizeof(w));
		memset(used, 0, sizeof(used));
		memset(pd, 0, sizeof(pd));
		memset(dis, 127, sizeof(dis));

		scanf("%d %d", &s, &t);
		cin >> x >> y >> z;

		for (int i = 1; i <= 998; i++)
		{
			w[i][i + 2] = y;
			pd[i][i + 2] = 1;
		}
		for (int i = 3; i <= 1000; i++)
		{
			w[i][i - 2] = z;
			pd[i][i - 2] = 1;
		}
		for (int i = 1; i <= 500; i++)
		{
			w[i][i * 2] = x;
			pd[i][i * 2] = 1;
		}

		dis[s] = 0;
		for (int i = 1; i <= 1000; i++)
		{
			int mini = 0;
			for (int j = 1; j <= 1000; j++)
				if (!used[j] && dis[j] < dis[mini])
					mini = j;
			if (mini == 0)
				break;
			used[mini] = 1;
			for (int j = 1; j <= 1000; j++)
				if (pd[mini][j] && dis[mini] + w[mini][j] < dis[j])
					dis[j] = dis[mini] + w[mini][j];
		}
		cout << "Case #" << pp << ":" << endl;

		if (dis[t] <= (1 << 30))
			printf("%d", dis[t]);
		else
			printf("-1");

		if (pp != u)
			printf("\n");
	}
	return 0;
}

Add a Comment

Your email address will not be published. Required fields are marked *