1212 12345666 1235 END
2 2 0
对DFS还是很头疼,搞不懂它是怎么运行的,有时候看着别人写的DFS看着看着就晕了,还得多做做这类的题目,上次网赛就有一道DFS暴搜,不会啊。。。。
本题的题意为给定一个由数字组成的字符串,向里面加入一个等号,和任意个加号,使得等式成立,问一共有多少种方案。
思路为枚举等号出现的位置,用equ表示,则1<=equ<=len-1, 也就是把等号加在第equ个数字后面,紧跟着第equ个数字。然后先DFS等号左边所有可能出现的情况,对应每个左边所出现的和lsum,再DFS等号右边所有可能出现的情况rsum,如果 rsum==lsum,那么有一种方案可行。
总结:通过DFS来搜出等号左边所有的状态,每一种状态压入栈中,然后从栈中取状态,再去DFS等号右边所有的状态,状态相等,则有一种方案可行。
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; char str[17]; int val[17][17]; int len; int ans; void cal() { memset(val,0,sizeof(val)); for(int i=1;i<=len;i++) for(int j=i;j<=len;j++) { for(int k=i;k<=j;k++) val[i][j]=val[i][j]*10+(str[k]-'0'); } } void dfsr(int lsum,int pos,int rsum)//dfs等号后边可能出现的情况 { if(pos>len) { if(rsum==lsum) ans++; return; } for(int k=pos;k<=len;k++)//注意是<=,因为最后一位也属于等号后边 dfsr(lsum,k+1,rsum+val[pos][k]);//注意是k+1 } void dfsl(int equ,int pos,int lsum)//dfs等号左边可能出现的情况,每种情况对应一个lsum(等号左边的和) { if(pos>equ)//当等号左边的数字的位置大于等号的位置时,搜索等号后边 dfsr(lsum,equ+1,0); for(int k=pos;k<=equ;k++)//注意是<=,equ代表的是等号加在第equ个数字后面 dfsl(equ,k+1,lsum+val[pos][k]); } int main() { while(cin>>(str+1)&&str[1]!='E') { ans=0; len=strlen(str+1); cal(); int equ; for(equ=1;equ<=len-1;equ++) dfsl(equ,1,0); cout<<ans<<endl; } return 0; }
[ACM] hdu 4403 A very hard Aoshu problem (DFS暴搜数字)
原文地址:http://blog.csdn.net/sr_19930829/article/details/39206145