您的位置:首页 > 其它

POJ 1416 DFS 加简单剪枝

2014-03-05 17:31 459 查看
剪枝的条件很明确,如果现在的 前面已经断开的纸带的和与当前纸带的和大于目标值,就不用向下搜索了。

注意一个细节是,第一个只能加到当前纸带上

其实这种题还是一个表示状态的问题

dfs(sum,cur,p)

表示前面的和 当前纸带的和 当前走到了第几个

这样足够清晰的描述问题了

#include <stdio.h>
#include <iostream>
#include <queue>
#include <algorithm>
#include <map>
#include <vector>
#include <cmath>
#include <string.h>
using namespace std;

#define READ freopen("acm.in","r",stdin)
#define ll long long
#define PII pair<int,int>
#define PDI pair<double,int>
#define MPI map<int,int>::iterator
#define fst first
#define sec second
#define MS(x,d) memset(x,d,sizeof(x))
#define INF 0x3f3f3f3f
#define ALL(x) x.begin(),x.end()
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define MAX 5500
#define ROOT 0,n-1,1
#define PB push_back
#define FOR(a,b,c) for(int a=b;a<c;a++)

int n,tar;
int tmp;
int cnt;// MAX 's count
char num[200];
int S[500];
int ans[500];
int ansCnt;
int top;
void dfs(int sum,int cur,int p)
{

if(sum+cur>tar)
return ;
if(p==n)
{
S[top++]=cur;
sum+=cur;
if(tmp==sum)
{
cnt++;
}
else if(sum>tmp&&sum<=tar)
{
tmp=sum,cnt=1;
for(int i=0;i<top;i++)
ans[i]=S[i];
ansCnt=top;
}
top--;
return ;
}
dfs(sum,cur*10+num[p]-'0',p+1);
if(p==0)
return ;
S[top++]=cur;
dfs(sum+cur,num[p]-'0',p+1);
top--;
}
bool check()
{
int tsum=0;
FOR(i,0,n)
tsum+=num[i]-'0';
if(tsum>tar)
return false;
return true;
}
int main()
{
while(scanf("%d%s",&tar,num))
{
if(tar==0&&num[0]=='0')
return 0;
tmp=0,cnt=0;
top=0;
n=strlen(num);
if(!check())
{
cout<<"error"<<endl;
continue;
}
dfs(0,0,0);
if(cnt>1)
{
cout<<"rejected"<<endl;
continue;
}
cout<<tmp<<" ";
for(int i=0;i<ansCnt;i++)
{
cout<<ans[i];
if(i!=ansCnt-1)
cout<<" ";
}
cout<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: