UVa 10400 记忆化搜索
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int INF = 32000; const int maxn = 105; int a[maxn]; char ans[maxn]; //a[i] = 1代表+,2代表-,3代表*,4代表/ ; int len,goal; bool vis[maxn][INF+1][2]; // vis[i][j][1]=1 表示计算完前i个数字的某种组合可以得到正j,dp[i][j][0]=1则为负j bool dfs(int u,int sum){ if(u == 1){ if(a[1] == sum ) return true; else return false; } if(sum >= 0 && vis[u][sum][1]) return false; else if(sum<0 && vis[u][-sum][0]) return false; int temp = sum - a[u]; if(temp > -INF && temp < INF){ ans[u] = '+'; if(dfs(u-1,temp)) return true; if(temp >= 0){ vis[u-1][temp][1] = true; } else{ vis[u-1][-temp][0] = true; } } temp = sum + a[u]; if(temp > -INF && temp < INF){ ans[u] = '-'; if(dfs(u-1,temp)) return true; if(temp >= 0){ vis[u-1][temp][1] = true; } else{ vis[u-1][-temp][0] = true; } } temp = sum * a[u]; if(temp > -INF && temp < INF){ ans[u] = '/'; if(dfs(u-1,temp)) return true; if(temp >= 0){ vis[u-1][temp][1] = true; } else{ vis[u-1][-temp][0] = true; } } if(sum % a[u]) return false; temp = sum / a[u]; if(temp > -INF && temp < INF){ ans[u] = '*'; if(dfs(u-1,temp)) return true; if(temp >= 0){ vis[u-1][temp][1] = true; } else{ vis[u-1][-temp][0] = true; } } return false; } void print(){ ans[len+1] = '='; for(int i=1;i<=len;i++){ printf("%d%c",a[i],ans[i+1]); } printf("%d\n",goal); } int main() { //freopen("E:\\acm\\input.txt","r",stdin); int T; cin>>T; while(T--){ scanf("%d",&len); for(int i=1;i<=len;i++) scanf("%d",&a[i]); scanf("%d",&goal); memset(vis,0,sizeof(vis)); if(dfs(len,goal)){ print(); } else printf("NO EXPRESSION\n"); } }