【C - Monkey and Banana】

最长上升子序列变种问题求解
博客围绕最长上升子序列的变种问题展开。将数字换成结构体 BLOCK,需求是求出最高高度。每个 BLOCK 可变为六块,按底面长排序后用正方形 dp 求解,还给出了代码的运行情况,首次求解 0ms、1388kB,二刷 15ms、1388kB。

思路:

  • 最长上升子序列的变种。
  • 数字改成了结构体 BLOCK,并且不仅要求出长度,本题需要求出最高的高度。
  • 每个 BLOCK 都是无限的,因此每块都可以变成六块。然后按底面的长排序(贪心),正方形 dp 求解。
  • 注意 ans 的使用(dp[i] 的意义)。

代码:

  • 核心:正方形 dp 求解最长上升子序列
#include <iostream>
#include <algorithm>

using namespace std;

int main(){
	int num[9] = {2 ,7, 1, 5, 6, 4 ,3 ,8 ,9};
	int dp[9];
	for(int i=0;i<9;i++){
		dp[i] = 1;
		for(int j=0;j<i;j++){
			if(num[i] > num[j]){
				dp[i] = max(dp[i] , dp[j] + 1);
			}
		}
		cout<<dp[i]<<endl;
	}
}
  • 0ms 1388kB
//0ms		1388kB 


#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 35 * 6 + 5; 

int T = 0;
int N;
int ans;
int dp[maxn];
struct BLOCK{
	int a,b,c;
	friend bool operator <(BLOCK l , BLOCK r)
	{
		return l.a == r.a ? l.b < r.b : l.a < r.a ;//实际上因为要求a、b都严格递增,并不需要判断b
	}
}block[maxn];int cnt;
void ADDBLOCK(int a,int b,int c){
	block[cnt].a = a;
	block[cnt].b = b;
	block[cnt].c = c;
	++cnt;
	return ;
}

void INIT(){
	cnt = 0;
	ans = 0;
	return ;
}

int main(){
	while(~scanf("%d" , &N) && N){
		++T;
		INIT();
		while(N--){
			int a,b,c;
			scanf("%d%d%d" , &a , &b , &c);
			ADDBLOCK(a,b,c);
			ADDBLOCK(a,c,b);
			ADDBLOCK(b,a,c);
			ADDBLOCK(b,c,a);
			ADDBLOCK(c,a,b);
			ADDBLOCK(c,b,a);
		}
		sort(block , block+cnt);//因为可以随意使用方块,相当于原序列不是序列而是集合(无序),所以排序,相当于是贪心的思想
		for(int i=0;i<cnt;i++){
			dp[i] = block[i].c;
			for(int j=0;j<i;j++)
				if(block[i].a > block[j].a && block[i].b > block[j].b)
					dp[i] = max(dp[i] , dp[j] + block[i].c);
			ans = max(ans , dp[i]);//千万不要忘,dp[i]是有限制条件的,必须使用block[i],它不一定是全局最优解。 
		}
		printf("Case %d: maximum height = %d\n" , T , ans);
	}
	return 0;
}

二刷:

  • 15ms 1388kB
//15ms		1388kB


#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 33;

int T; 
int N;
struct NODE{
	int x,y;
	int z;
	friend bool operator < (NODE a , NODE b)
	{
		if(a.x == b.x)
			return a.y > b.y;
		return a.x > b.x;
	}
}node[maxn * 6];int cnt;
void ADDNODE(int x,int y,int z){
	node[cnt].x = x;
	node[cnt].y = y;
	node[cnt].z = z;
	++cnt;
	return ;
}
struct DP{
	int A,B;
	int height;
}dp[maxn * 6];

int main(){
	while(cin>>N && N){
		cnt = 0;
		memset(dp , 0 , sizeof(dp));
		for(int i=1;i<=N;i++){
			int x,y,z;
			cin>>x>>y>>z;
			ADDNODE(x,y,z);
			ADDNODE(x,z,y);
			ADDNODE(y,x,z);
			ADDNODE(y,z,x);
			ADDNODE(z,x,y);
			ADDNODE(z,y,x);
		}
		sort(node , node + cnt);
		int MAX = 0;
		for(int i=0;i<cnt;i++){			
			int j;
			int place_id = 0;
			int place_height = 0;
			for(j=i-1;j>=0;j--)
				if(dp[j].A > node[i].x && dp[j].B > node[i].y)
					if(dp[j].height > place_height){
						place_height = dp[j].height;
						place_id = j;
					}
			//注意,这里需要完全遍历! 
			if(place_id)
				dp[i].height = place_height + node[i].z;
			else
				dp[i].height = node[i].z;
			dp[i].A = node[i].x;
			dp[i].B = node[i].y;
			MAX = max(MAX , dp[i].height);
		}
		printf("Case %d: maximum height = %d\n" , ++T , MAX);
	}
	return 0;
}
### 实现猴子摘香蕉问题的 C 语言程序 为了实现猴子移动到箱子并最终拿到香蕉的过程,完整的解决方案应包括以下几个部分: 1. **定义数据结构** 使用结构体来表示房间内的各个对象及其属性。这有助于清晰地管理不同实体的状态。 2. **初始化状态** 设置初始条件,如猴子、箱子和香蕉的具体位置。 3. **目标检测** 定义何时认为任务已完成的标准,即当猴子站在箱顶且能触及香蕉时。 4. **动作执行** 编写一系列操作函数用于改变当前场景中的物体相对位置关系,比如`move_monkey()` 和 `push_box()` 5. **主循环控制** 创建一个主循环来进行交互式的命令解析与响应机制,直到达成目的为止。 以下是基于上述原则构建的一个简化版C语言源码框架[^1]: ```c #include <stdio.h> #include <stdbool.h> // Define the structure to hold positions of objects. typedef struct { int monkey; int box; int banana; } State; void move_monkey(State *s, int new_pos); bool can_reach_banana(const State* s); int main(void){ // Initialize state with given locations (example values). State initialState = { .monkey=0 , .box=2 , .banana=3 }; printf("Initial setup:\nMonkey at %d\nBox at %d\nBananas at %d.\n", initialState.monkey, initialState.box, initialState.banana ); while (!can_reach_banana(&initialState)){ char action[8]; scanf("%7s",action); // Read user input if(strcmp(action,"go")==0 || strcmp(action,"Go")==0){ int pos; scanf("%d",&pos); move_monkey(&initialState,pos); printf("Moved monkey to position:%d\n",initialState.monkey); } else{ puts("Invalid command."); } // Print updated status after each step printf("\nCurrent Status:\n"); printf("Monkey is now at %d\n", initialState.monkey); printf("The Box remains at %d\n", initialState.box); printf("And Bananas are still hanging from point %d\n", initialState.banana); } puts("Goal achieved! The monkey has reached the bananas!"); } /// Function implementations below... void move_monkey(State *s,int newPos){ (*s).monkey=newPos; } bool can_reach_banana(const State* s){ return ((*s).monkey==(*s).box && (*s).box==(*s).banana)?true:false ; } ``` 此代码实现了基本功能,允许通过简单的命令行界面指导猴子行动直至成功获取香蕉。然而,这段代码仅提供了一个基础版本;实际应用可能还需要考虑更多细节,例如更复杂的环境建模或者错误处理等特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值