Monkey and Banana

Monkey and Banana

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1093

ps:该题个人认为我的初始方法比较暴力,可能不是暴力解,,这是看了别人一点思路直接自己写的,,没看具体代码,可能部分需要改,,持续更新

一开始写了一种终极无敌暴力的递归做法。。个人认为挺好理解的hhh

因为这题砖头是三维的,而且可以随意转动,并且每个砖头可以选取无数多个。。所以我直接把1个砖头转化为6个砖头,这样子随意转动问题就解决了。。。

然后我就像搜索一样做,写一个recursion(int x, int y, int i)的函数,,该函数表示堆叠过程中最顶一块砖头的长和宽分别为 x 和 y ,i 是砖头的编号。
这里注意!!如果只用递归的话,第三个参数i也是可以不用的
之后的操作就是每次递归去找适合的砖头放在它上面并继续进入递归,,用一个变量flag表示上面还能不能放砖头,如果不能就返回0;

结果没错!肯定是非常暴力的不能AC的,但是!!再把递归转记忆化搜索就好了这里不解释记忆化搜索
代码如下:

import java.util.Scanner;

public class MonkeyAndBanana {
	static int[] memo = new int[10000];
	static int[][] box = new int[10000][3];
	static int n;
	static int recursion(int x, int y, int i) {
		if(memo[i] != -1)
			return memo[i];
		boolean flag = true;			//flag变量用来记录上方是否还能放砖头	
		for(int j = 0; j < 6*n; j++) {
			if(box[j][0] < x && box[j][1] < y) {
				flag = false;
				int now = recursion(box[j][0], box[j][1], j)+box[j][2];
				memo[i] = now > memo[i]? now : memo[i];
			}
		}
		if(flag)			//不能就跳出
			return 0;
		return memo[i];
	}
	
	static void process(int i, int x, int y, int z) {	//预处理,把输入的1个砖块转化为6个方向的砖块
		box[i][0] = x;
		box[i][1] = y;
		box[i][2] = z;
	}
	static void process1(int n) {		//预处理,把记忆数组初始化为-1
		for(int i = 0; i < 6*n; i++) {
			memo[i] = -1;
		}
	}
/*	static void display() {				//测试函数
		for(int i = 0; i < 6*n; i++) {
			for(int j = 0; j < 3; j++) {
				System.out.print(box[i][j]+" ");
			}
			System.out.println();
		}
	}*/
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int count = 1;
		while(sc.hasNext()) {
			n = sc.nextInt();
			if(n == 0)
				break;
			for(int i = 0; i < 6*n;) {
				int x = sc.nextInt();
				int y = sc.nextInt();
				int z = sc.nextInt();
				process(i++, x, y, z);
				process(i++, x, z, y);
				process(i++, y, x, z);
				process(i++, y, z, x);
				process(i++, z, x, y);
				process(i++, z, y, x);
			}
			int ans = 0;
			process1(n);
			for(int i = 0; i < 6*n; i++) {
				int now;
				if(memo[i] != -1)
					now = memo[i];
				else
					now = recursion(box[i][0], box[i][1], i)+box[i][2];
				ans = ans > now? ans:now;
			}
			
			System.out.println("Case "+count+": maximum height = "+ans);
			count++;
		//display();
		}
	}
	
}

理解了别人的最优解会更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
#include <stdio.h> int main(){ void gobox(int a,int b); void getbox(); void findbanana(int a,int b); void getbanana(); int monkey,banana,box; printf("请依次输入猴子,香蕉,箱子 的位置\n"); printf("猴子的位置:"); scanf("%d",&monkey); printf("香蕉的位置:"); scanf("%d",&banana); printf("箱子的位置:"); scanf("%d",&box); printf("-----------------------------------\n"); if(monkey!=box){ printf("猴子够不到香蕉,要先去搬箱子:"); gobox(monkey,box); getbox(); if(box!=banana){ printf("猴子需要搬着箱子去找到香蕉:"); findbanana(banana,box); getbanana(); }else{ printf("香蕉就在箱子的上面\n"); getbanana(); } }else{ printf("箱子就在猴子旁边,猴子拿到了箱子"); getbox(); if(box!=banana){ printf("猴子需要搬着箱子去找到香蕉:"); findbanana(banana,box); getbanana(); }else{ printf("香蕉就在箱子的上面\n"); getbanana(); } } } void gobox(int a,int b){ int flag; flag = b - a; if(flag>0){ printf("Run(monkey,box)\n"); printf("猴子需要向右移动%d步拿到箱子\n",flag); }else{ printf("Run(monkey,box)\n"); printf("猴子需要向左移动%d步拿到箱子\n",flag); } } void findbanana(int a,int b){ int flag; flag=b-a; if(flag>0){ printf("Run(monkey,banana)\n"); printf("猴子需要向左搬着箱子移动%d步找到香蕉\n",flag); }else{ printf("Run(monkey,banana)\n"); printf("猴子需要向右搬着箱子移动%d步找到香蕉\n",flag); } } void getbox(){ printf("猴子拿到了箱子:"); printf("Getbox(monkey,box)\n"); } void getbanana(){ printf("猴子踩在箱子上拿到了香蕉:"); printf("Getbanana(monkey,banana)\n"); }请输出主要数据定义和主要功能模块设计
05-25

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值