首页 > 代码库 > UVa11882,Biggest Number
UVa11882,Biggest Number
搜索+剪枝
如此水的一个题,居然搞了一上午
出错在bfs与dfs时共用了一个vis数组,导致bfs完后返回dfs应该能访问到的点访问不到
自己想怎么剪枝,想了几个剪枝方法,又证明,又推翻,再想,再证明,再推翻用了好长时间T T自己还是水的不行啊
两个剪枝:
1.若,当前求出来的解now的长度+当前状态下从now节点(因为可能有多个连通块,用vis[]判断未访问到的节点是不行的)开始能访问到的节点的个数(bfs遍历即可)<当然ans的长度,那么剪枝。这样大概能减掉一半的枝叶。但是可能还会超时
2.在剪枝1的条件下,若==呢?剪枝1时bfs的时候存下所以当前状态下能访问到的点,对这些点降序排序然后接到now后面,那么得到的就是当前状态下可能搜到的最优解,若该解仍小于ans,那么剪枝。又能减掉一大半的枝叶。
总结:
这题虽然花了我不少时间,但是也能总结出不少东西。
剪枝时若当前状态下可能得到的最优解仍然小于ans,那么就可以剪枝。
这可能就是所谓的最优化剪枝吧。
#include <iostream>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <vector>using namespace std;int r,c,map[20][20],vis[20][20],d[40][2],dtop,ans,f[20][20],maxlen,cc;int dx[]={0,0,1,-1},dy[]={1,-1,0,0};vector<int> cnt;struct Node{ int x,y,len;};int init(){ memset(vis,0,sizeof(vis)); memset(map,0,sizeof(map)); dtop=0; char ch; for (int i=0;i<r;i++) for (int j=0;j<c;j++){ cin>>ch; if (ch==‘#‘) map[i][j]=-1; else {map[i][j]=ch-‘0‘;d[dtop][0]=i;d[dtop][1]=j;dtop++;} }}int ok(int x,int y){ if (x>=0&&y>=0&&x<r&&y<c) return 1; return 0;}int len(int s){ return (log10(s)+1.5);}int bfs(int x,int y){ int len=0; queue<Node> q; Node u; int bv[20][20]; for (int i=0;i<r;i++) for (int j=0;j<c;j++) bv[i][j]=vis[i][j]; u.x=x;u.y=y;u.len=1; q.push(u); while (!q.empty()){ u=q.front(); for (int i=0;i<4;i++){ Node v; v.x=u.x+dx[i];v.y=u.y+dy[i];v.len=u.len+1; if (ok(v.x,v.y)&&!bv[v.x][v.y]&&map[v.x][v.y]>0){ bv[v.x][v.y]=1; len++; cnt.push_back(map[v.x][v.y]); q.push(v); } } q.pop(); } return len;}int sum(int s){ sort(cnt.begin(),cnt.end(),greater<int>()); for (int i=0;i<cnt.size();i++) s=s*10+cnt[i]; return s;}int dfs(int x,int y,int s){ s=s*10+map[x][y]; cc++; cnt.clear(); if (ans){ int l=bfs(x,y); int t=len(s)+l; if ((len(s)+l)<len(ans)) return 0; if ((len(s)+l)==len(ans)&&sum(s)<ans) return 0; } int nextx,nexty; for (int i=0;i<4;i++){ nextx=x+dx[i];nexty=y+dy[i]; if (ok(nextx,nexty)&&!vis[nextx][nexty]&&map[nextx][nexty]>0){ vis[nextx][nexty]=1; dfs(nextx,nexty,s); vis[nextx][nexty]=0; } } ans=max(ans,s); return 1;}int main(){ while (cin>>r>>c&&r&&c){ init(); ans=0; maxlen=0; /*for (int k=0;k<dtop;k++){ memset(vis,0,sizeof(vis)); vis[d[k][0]][d[k][1]]=1; f[d[k][0]][d[k][1]]=bfs(d[k][0],d[k][1]); }*/ for (int k=0;k<dtop;k++){ memset(vis,0,sizeof(vis)); vis[d[k][0]][d[k][1]]=1; dfs(d[k][0],d[k][1],0); } cout<<ans<<endl; }}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。