买零食 HihoCoder - 1272 (大爆搜DFS)

小Ho很喜欢在课间去小卖部买零食。然而不幸的是,这个学期他又有在一教的课,而一教的小卖部姐姐以冷若冰霜著称。第一次去一教小卖部买零食的时候,小Ho由于不懂事买了好一大堆东西,被小卖部姐姐给了一个“冷若冰霜”的眼神,食欲都下降了很多。

从那以后,小Ho就学乖了,去小卖部买东西只敢同时买3包以内的零食,并且价格加起来必须是5的整数倍,方便小卖部姐姐算价格。

但是小Ho不擅长计算,所以他把小卖部里所有零食的价格以及他对这个零食的渴望度都告诉了你,希望你能够帮他计算出在不惹恼小卖部姐姐的前提下,能够买到零食的渴望度之和最高是多少?

Input

每个输入文件包含多组测试数据,在每个输入文件的第一行为一个整数Q,表示测试数据的组数。

每组测试数据的第一行为一个正整数N,表示小卖部中零食的数量。

接下来的N行,每行为一个正实数A和一个正整数B,表示这种零食的价格和小Ho对其的渴望度。

一种零食仅有一包。

对于100%的数据,满足1 <= Q <= 10,1<=N<=50,0<A<=10,1<=B<=100。

对于100%的数据,满足A的小数部分仅可能为0.5或0。

Output

扫描二维码关注公众号,回复: 5719267 查看本文章

对于每组测试数据,输出一个整数Ans,表示小Ho可以获得最大的渴望度之和。

Sample Input

1
4
0.5 6
4.5 7
5.0 4
2.0 9

Sample Output

17

首先数据量不是很大,我们想到了DFS 穷尽搜索的办法,将每个情况都搜索一遍,把每种情况都搜索一遍,最后取那个最大值。递归的思想大家都是懂得,下面我就直接说函数部分怎么写:
双重DFS

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<bits/stdc++.h>
#include<set>
#include<vector>
const int maxn=1010;
using namespace std;
#include<map>
#include<string>
#include<string.h>
#include<cmath>
typedef long long ll;
typedef pair<int,int> p;

double a[maxn];
int b[maxn];
int ans;
int num;

bool check(double qian)
{
	int a=ceil(qian);
	int b=floor(qian);
	 
	if(a==b&&a%5==0)
		return true;
	else
		return false;
}

void dfs(double qian,int du,int i,int t)
{
	if(i>num)
		return ;
	if(t>3)
		return ;
	if(check(qian)&&t<=3)
	{
		ans=max(ans,du);
		
	}	
	dfs(qian+a[i],du+b[i],i+1,t+1);
	dfs(qian,du,i+1,t);	
}

int main()
{
	int t;
	cin>>t;
	
	while(t--)
	{
		ans=0;
		cin>>num;
		for(int i=0;i<num;i++)
		{
			cin>>a[i]>>b[i];

		}
		dfs(0,0,0,0);
		cout<<ans<<endl;
	}
	return 0;
}

这个两个DFS递归是 1.当前零食拿 2.当前零食不拿 ,就这两种选择,于是写两个递归,使这两种情况相互交错,达到更多更复杂的情况,思想有点难实现,代码还是很好实现的。

另一种就是普通的DFS ,:


#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<bits/stdc++.h>
#include<set>
#include<vector>
const int maxn=1010;
using namespace std;
#include<map>
#include<string>
#include<string.h>
#include<cmath>
typedef long long ll;
typedef pair<int,int> p;

double a[maxn];
int b[maxn];

int ans;
int num;
int vis[maxn];

void dfs(double qian,int du,int t)
{
	if(t>3)	
	    return ;
		
	if(((int)(qian)==qian)&&t<=3)
	{
		if((int)qian%5==0&&qian!=0)
		ans=max(ans,du);
		
	}	
	for(int i=0;i<num;i++)
	{
		if(vis[i])
			continue;	
	
		vis[i]=1;
		dfs(qian+a[i],du+b[i],t+1);
		vis[i]=0;
	}	
}

int main()
{
	int t;
	cin>>t;
	
	while(t--)
	{	
		memset(vis,0,sizeof(vis));
		ans=0;
		cin>>num;
		for(int i=0;i<num;i++)
		{
			cin>>a[i]>>b[i];

		}
		dfs(0,0,0);
		cout<<ans<<endl;
	}
	return 0;
}

 普通版本可能对于新手(我也是新手)来说,更好理解,其实都一样的。

 上面是双重 DFS 版本,下面是普通版本。

猜你喜欢

转载自blog.csdn.net/tsam123/article/details/88378915
今日推荐