P4817 Fruit Feast G

最开始拿到这道题的时候,题目中其实只规定了两种水果的饱食度,可以理解成价值或是重量,在不超过T的情况求最大值。第一眼看过去感觉就是装箱问题(背包),只不过这道题用的是完全背包,但是考虑到喝水的情况,做背包的时候,反正没做过这种题,但是我们可以把它转移为搜索的做法,有一种01背包的思路

每一次搜索,把吃橙子和柠檬的情况都处理一次,又因为只能喝一次水,我们只需要用bool类型的判断一下就好了,记住处理越界的情况

#include<bits/stdc++.h>
using namespace std;
int a,b,t;
int ans[10005];
int m;
void dfs(int v,int hs) {
	if(v>t) return ;
	if(v==t) {
		ans[++m]=t;
		if(m!=1) return ;
	}
	if(v>ans[1]) ans[1]=v;
	if(hs==1) {
		dfs(v/2,0);
	}
	dfs(v+a,hs);
	dfs(v+b,hs);
}
int main() {
	cin>>t>>a>>b;
	dfs(0,1);
	cout<<ans[1];
	return 0;
}

但是这个程序只能得76分,因为TLE了,就是这道题的瓶颈。因为在深搜的时候,就会处理所有可能的答案和情况,导致超时,又因为是调用函数,不容易中途退出,所以在写的时候应该换一种思路

我们用一个数组来存储搜到的答案,搜到的第一个答案就是正解,对于其他所有的情况,想都不要想直接return,节省多出来的时空间。除了这一种做法,还有一个比较简单的,可能是我对电脑程序运行不太了解的原因,可以直接使用exit(0),强制退出程序

#include<bits/stdc++.h>
using namespace std;
int a,b,t;
int ans[1000005];
int m;
void dfs(int v,int hs) {
	if(m>1) return ;
	if(v>t) return ;
	if(v==t) {
		ans[++m]=t;
		if(m!=1) return ;
	}
	if(v>ans[1]) ans[1]=v;
	if(hs==1) {
		dfs(v/2,0);
	}
	dfs(v+a,hs);
	dfs(v+b,hs);
}
int main() {
	cin>>t>>a>>b;
	dfs(0,1);
	cout<<ans[1];
	return 0;
}
posted @ 2020-06-08 20:19  Poetic_Rain  阅读(85)  评论(0编辑  收藏  举报