ACM-ICPC 2018 徐州赛区网络预赛 B. BE, GE or NE

版权声明: https://blog.csdn.net/King8611/article/details/82560866

题目链接:https://nanti.jisuanke.com/t/31454

题目大概意思:

刚才写这篇博客的时候,把意思打出来了,结果不小心关了,然后没保存上。这次就不解释了。

大概思路:

比较难想,但是想到了就不难了。

就是一个dfs+记忆数组,然后把搜索过的结果存起来,方便下次用。

复杂度:n*200

代码:

import java.io.*;
import java.util.*;

import javax.swing.JOptionPane;

public class Main {
	static int sum=0;
	static int arr[][];
	static int n,m,k,l;
	static int dp[][];								//一个dp记忆搜索过的路线,防止超时
	static int inf=Integer.MAX_VALUE;
	static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
	static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
	public static void main( String args[])throws Exception{
		
													//因为分数会出现负数,为了避免这个情况,分数相关的数据+100就行了
		n=getInt();
		m=getInt()+100;
		k=getInt()+100;
		l=getInt()+100;
		arr=new int[n][3];
		dp=new int[n][301];						
		for(int i=0;i<n;i++) 
			for(int j=0;j<300;j++)
				dp[i][j]=inf;
		for(int i=0;i<n;i++) 
			for(int j=0;j<3;j++)
				arr[i][j]=getInt();
		int ans=dui(0,m);
		if(ans>=k)
			System.out.println("Good Ending");
		else if(ans<=l) 
			System.out.println("Bad Ending");
		else 
			System.out.println("Normal Ending");
	}
	static int dui(int i,int now) {						//一个伟大的dfs,不要以为他超时
		//i表示第i次操作,now表示当前的分数。
		if(i==n)
			return now;
		if(dp[i][now]!=inf)								//如果更新过这个点,那就没必要往下继续更新了,就要换线路了。
			return dp[i][now];
		if(i%2==0) {									//第一个人拿的情况
			int ans=-100;
			
														//搜索三个情况可能出现的所有结果
			if(arr[i][0]>0) {
				int nn=Math.min(now+arr[i][0],200);	
				ans=Math.max(ans, dui(i+1,nn));			//第一个人当然是想拿最大啦
			}
			if(arr[i][1]>0) {
				int nn=Math.max(now-arr[i][1], 0);
				ans=Math.max(ans, dui(i+1,nn));		
			}
			if(arr[i][2]>0) {
				ans=Math.max(ans, dui(i+1,200-now));
			}
			dp[i][now]=ans;
			return ans;									//储存当前的情况,可以保证二次利用,以防超时。
			
		}												//第二个人想要最小,和第一个类似
		else {
			int ans=200;
			if(arr[i][0]>0) {
				int nn=Math.min(now+arr[i][0],200);
				ans=Math.min(ans, dui(i+1,nn));
			}
			if(arr[i][1]>0) {
				int nn=Math.max(now-arr[i][1], 0);
				ans=Math.min(ans, dui(i+1,nn));		
			}
			if(arr[i][2]>0) {
				ans=Math.min(ans, dui(i+1,200-now));
			}
			dp[i][now]=ans;
			return ans;
		}
	}
	static int getInt() throws IOException{
		in.nextToken();
		return (int) in.nval;
	}
}

猜你喜欢

转载自blog.csdn.net/King8611/article/details/82560866