Visitors hit counter dreamweaver

poj 1416 DFS

   转自:http://hi.baidu.com/tracyangrad/blog/item/3db0edd1b7f4c2d1a8ec9a37.html 

  他的分析很好。特别是这图,让我对递归有更直观的认识。好好学习下他的方法。 

题目描述:给定一个target数字,一个num,要求分解num,使得num被分解后所得的各数之和小于并且最接近target,这个和就是最优解。若无最优解输出error,若同时多个最优解,则输出rejected。
思路:深搜,每次找个可行解就保存,当作最优解,若后来的更优,则更新。

 


 

#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;

int target,sum,len,Max,p;
int tot; //记录最优路径时包含的数的个数
int num[6]; //to record each bit of the number
int best[6]; //record the best path
int tem[6];
int vis[1000000];
void dfs(int cur,int pos,int sum)
{
if(sum>target) return; //不满足
if(pos>=len)
{
if(sum==Max)
{
vis[Max]++;
}
else if(sum>Max)
{
Max=sum;
vis[Max]++;
for(int i=0; i<p; i++)
{
best[i]=tem[i]; //把最优路径记录下来
}
tot=p; //最优路径包含的数的个数
}
}
else //下面是关键
{
tem[p++]=cur*10+num[pos];
dfs(0,pos+1,sum+cur*10+num[pos]); //累加现有的组合
tem[p--]=0;
if(pos<len-1)
{
dfs(cur*10+num[pos],pos+1,sum); //合并数字找最优解
}
}
}

int main()
{
freopen("acm.txt","r",stdin);
char s[7];
while(scanf("%d%s",&target,s)!=EOF && target && s[0]!='0')
{
tot=p=Max=0;
memset(num,0,sizeof(num));
memset(best,0,sizeof(best));
memset(vis,0,sizeof(vis));
memset(tem,0,sizeof(tem));
len=strlen(s);
for(int i=0 ; i<len; i++)
{
num[i]=s[i]-'0';
}
dfs(0,0,0);
if(vis[Max]==1)
{
printf("%d",Max);
for(int i=0; i<tot; i++)
{
printf(" %d",best[i]);
}
printf("\n");
}
else if(vis[Max]>1)
{
printf("rejected\n");
}
else if(vis[Max]==0)
{
printf("error\n");
}
}
return 0;
}


posted @ 2012-03-22 22:17  Jason Damon  阅读(932)  评论(0编辑  收藏  举报