The escape of the 2007 noip popular group watchmen

[Topic description]

The demon hunter You Chian is ambitious. He betrayed the night elves and led Naga, who was hiding in the bottom of the sea, in an attempt to rebel: the watchman encountered a siege in the confrontation with Yudian. He was trapped on a large deserted island. In order to kill the watchman, Yudian began to curse the deserted island, which will soon sink. By then, everyone on the knife will be killed: the running speed of the watchman is 17m/s, It is impossible to escape from the deserted island at this speed. Fortunately, the watchman has the blinking spell, which can move 60m within 1s, but every time the blinking spell is used, it consumes 10 mana. The mana recovery speed of the watchman is 4 points/s, and it can only be recovered when resting on the spot.

It is now known that the initial value of the watchman’s magic is M, the distance S between his initial position and the exit of the island, and the time T when the island sinks. Your task is to write a program to help the watchman calculate how to escape from the deserted island in the shortest time. If it can't escape, output the farthest distance the watchman can walk in the remaining time. Note: The running, flashing or resting activities of the watchman are all measured in seconds (s). And the duration of each activity is an integer number of seconds. The unit of distance is meter (m).

Input The
input file escape.in is only one line, including three non-negative integers M, S, T separated by spaces.

Output The
output file escape.out contains two lines:

The first line is the string "Yes" or "No" (case sensitive), that is, whether the watchman can escape the desert island.

The second line contains an integer, the first line "Yes" (case sensitive) means the shortest time to escape from the deserted island

When the first line is "No" (case sensitive), it means the longest distance the watcher can travel.

Sample input
39 200 4
Sample output
No
197
indicates that
30% of the data meets: 1 <= T<= 10, 1 <=S<= 100
50% of the data meets: 1 <= T <= 1000, 1 <= S <= 10000
100% of the data satisfies: 1 <= T <= 300000, 0 <= M<=1000 1 <=S <= 10^8

【analysis】

1. Search

Memoized search is fine, but in principle, if the memory limit is not large enough, 30w dfs will burst the stack, here should not be used dfs but bfs...
First search for all f [i] [j] f[i][j ]F [ i ] [ j ] results,F [i] [j] denotes the i-th second, the amount of remaining blue j is the maximum distance that can be traveled F [i] [j] denotes the i-th second, the remaining amount of blue j The longest distancef [ i ] [ j ] table shows the first i seconds , remaining more than blue amount is j can take the most far away from the last f traverse the entire array to find an optimal solution to

#include<bits/stdc++.h>
using namespace std;
int m,s,t,ans,anstime;
int f[300105][15]={0};
void dfs(int nowtime,int way,int value){
	if (nowtime > t) return;        //若超出规定时间t则结束搜索
	if (f[nowtime][value] >= way) return;  //对当前状态判断是否比之前记录过的状态更优,若更优才继续搜索
	f[nowtime][value] = way;
	if (way >= s) return;     // 若当前移动的距离已经超过目标距离了,那么之后的搜索都是无意义的
	if (value >= 10){    //若当前蓝量足够闪烁,那么显然立刻闪烁是最优解
		dfs(nowtime+1,way+60,value-10);
	}
	else{
		//搜索移动和停止在原地回蓝两种状态
		dfs(nowtime+1,way,value+4);
		dfs(nowtime+1,way+17,value);
	}
}

int main() 
{
	memset(f,-1,sizeof(f));
	scanf("%d%d%d",&m,&s,&t);
 	int starttime = 0,start = 0;
	while (m >= 10 && starttime < t && start < s){
		//毋庸置疑,一开始将初始有的蓝全部用完
		m-=10;
		start+=60;
		++starttime;
	}
	//两个特殊情况,即蓝没用完,却已经逃离了,或蓝没用完,时间到了
	if (start >= s){
		printf("Yes\n%d",starttime);
		return 0;
	}
	if (starttime == t){
		printf("No\n%d",start);
		return 0;
	}
	dfs(starttime,start,m);
	int ans = 0;
	//在所有的状态中搜索一个最优解,若某次搜索发现已经逃离,那么当前时间就是最小时间
	for(int i = 1 ; i <= t ; ++i)
		for (int j = 0; j <= 14 ; ++j)
		{
			ans = max(ans,f[i][j]);
			if (f[i][j] >= s){
				printf("Yes\n%d",i);
				return 0;
			}
		} 	
 	printf("No\n%d",ans);
 	return 0;
}

2.dp

Use F[t] to represent the farthest distance the watcher can travel in t time, and G[t] represents the farthest distance the watcher can walk in t time using only the blinking spell. Then the corresponding state transition equation is
{F [0] = G [0] = 0 F [t] = max (F [t − 1] + 17, G [t]) \begin{cases} F[0] = G[0] = 0 \\ F[t] = max(F[t-1] + 17, G[t]) \end{cases}{ F[0]=G[0]=0F[t]=max(F[t1]+17,G[t])

#include <stdio.h>

int main() {
    int m, s, t;
    int i, d1, d2; 
    scanf("%d%d%d", &m, &s, &t);
    d1 = d2 = 0;
    for (i = 1; i <= t; i++) {
        if (m >= 10) {
            d1 += 60; m-= 10;
        } else {
            m += 4;
        }
        if (d1 > d2 + 17) d2 = d1;
        else d2 += 17;
        if (d2 >= s) break;
    }
    if (i > t) printf("No\n%d\n", d2);
    else printf("Yes\n%d\n", i);
    return 0;
}

Guess you like

Origin blog.csdn.net/jnxxhzz/article/details/86669979