HDU 5937 Equation 搜索+剪枝

http://acm.hdu.edu.cn/showproblem.php?pid=5937
题目大意:给出 1 − 9 1-9 19每个数字的个数,问最多能组成多少个不同的形如 a + b = c a+b=c a+b=c的式子。( 1 + 2 = 32 + 1 = 31 + 4 = 5 1+2=3 2+1=3 1+4=5 1+2=32+1=31+4=5这些都视为不同情况)
思路:真的爆搜就过了,只需要一个特别简单的剪枝。通过枚举发现最多只有 36 36 36个式子,且数字 i i i只需要用到 36 − i 36-i 36i次。直接爆搜 O ( 2 36 ) O(2^{36}) O(236)会超时,需要一个小剪枝:假设我们当前该判断第 c u r cur cur个式子,且有 n u m num num个式子成立,答案为 a n s ans ans,那么当 36 − c u r + n u m < = a n s 36-cur+num<=ans 36cur+num<=ans时,就没有搜下去的必要了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

int a[10],d[40][3],vis[12],ans;

void init()
{
    int cnt=0;
    for(int i=1;i<=9;i++)
	{
		for(int j=1;j+i<=9;j++)
        {
            d[cnt][0]=i;
            d[cnt][1]=j;
            d[cnt++][2]=i+j;
            vis[i]++;vis[j]++;vis[i+j]++;
        }
	}
	//cout<<cnt<<endl; 36个
}

void dfs(int cur,int num)
{
	if(36-cur+num<=ans||cur==36)
		return ;
	--a[d[cur][0]],--a[d[cur][1]],--a[d[cur][2]];
	if(a[d[cur][0]]>=0&&a[d[cur][1]]>=0&&a[d[cur][2]]>=0)
	{
		ans=max(ans,num+1);
		dfs(cur+1,num+1);
	}
	++a[d[cur][0]],++a[d[cur][1]],++a[d[cur][2]];
	dfs(cur+1,num);
}

int main()
{
	init();
//	for(int i=1;i<=9;i++)
//		cout<<vis[i]<<' '; 17-i 个即可
	int t;
	scanf("%d",&t);
	int times=0;
	while(t--)
	{
		bool flag=0;
		for(int i=1;i<=9;i++)
		{
			scanf("%d",&a[i]);
			if(a[i]<17-i)
				flag=1;
			else
				a[i]=17-i;
		}
		if(!flag)
			printf("Case #%d: %d\n",++times,36);
		else
		{
			ans=0;
			dfs(0,0);
			printf("Case #%d: %d\n",++times,ans);
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值