HDU1539Shredding Company(DFS+保存最优路径)

题目大意:给你一个目标值和一段数字串,你要把这个串进行分割求和,让结果趋近于目标值并且不大于他

思路:搜索,每次一个x代表你要分割串的头位置,即最高位,sum代表在x位置之前分割求和的结果,k代表最优答案的位数

小结:一开始是想用一个栈保存最优答案的值,但是直接在每次搜的时候就改变这个栈了,结果最优答案可能被更替,导致一晚上没能解决这个问题,忘了还可以用一个中间数组进行存值,等到要改变最优值时再换答案。基础做法!!牢记

加上按位和的剪枝从15ms变成0ms代码

AC代码如下:

#include<cstdio>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;

char s[10000],c;
int data[10000],n,flag,MAX,size,t,answer[10000],temp[10000];

void dfs(int x,int sum,int k)
{
	if(x==n)
	{
		if(MAX<=sum && sum<=size)
		{
			if(flag && MAX<sum)  //之前有重复并且此次要更新
				flag=0;
			else if(MAX==sum)  //此次重复
				flag=1;
			MAX=sum;
			t=k;
			for(int i=0;i<t;i++)
				answer[i]=temp[i];
		}
		return ;
	}
	int i,l=0;
	for(i=x;i<n;i++)
	{
		l=l*10+data[i];
		if(l>=size) break;  //发现到这里已经比那个想要靠近的数来得大或者等于了  之后就不用切了
		temp[k]=l;
		dfs(i+1,sum+l,k+1);
	}
	return ;
}

int main()
{
	int i,l,k;
	while(~scanf("%d%s",&size,s) && (size||strcmp(s,"0")))
	{
		n=strlen(s);
		for(MAX=i=l=flag=t=k=0;i<n;i++)
		{
			data[i]=s[i]-'0';
			k+=data[i];
			if(data[i]>=size || k>size)
			{
				flag=1;
				break;
			}
			l=l*10+data[i];
		}
		if(flag)  //剪枝,如果数中有某段数本身或者按位和大于目标就去掉
			puts("error");
		else if(l==size)
			printf("%d %d\n",l,size);
		else
		{
			dfs(0,0,0);
			if(flag)
				puts("rejected");
			else
			{
				printf("%d",MAX);
				for(i=0;i<t;i++)
					printf(" %d",answer[i]);
				printf("\n");
			}
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小胡同的诗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值