码迷,mamicode.com
首页 > 其他好文 > 详细

UVa11882,Biggest Number

时间:2014-07-31 13:15:16      阅读:492      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   art   

搜索+剪枝

如此水的一个题,居然搞了一上午

出错在bfs与dfs时共用了一个vis数组,导致bfs完后返回dfs应该能访问到的点访问不到

自己想怎么剪枝,想了几个剪枝方法,又证明,又推翻,再想,再证明,再推翻用了好长时间T T自己还是水的不行啊

两个剪枝:

1.若,当前求出来的解now的长度+当前状态下从now节点(因为可能有多个连通块,用vis[]判断未访问到的节点是不行的)开始能访问到的节点的个数(bfs遍历即可)<当然ans的长度,那么剪枝。这样大概能减掉一半的枝叶。但是可能还会超时

2.在剪枝1的条件下,若==呢?剪枝1时bfs的时候存下所以当前状态下能访问到的点,对这些点降序排序然后接到now后面,那么得到的就是当前状态下可能搜到的最优解,若该解仍小于ans,那么剪枝。又能减掉一大半的枝叶。

总结:

  这题虽然花了我不少时间,但是也能总结出不少东西。

  剪枝时若当前状态下可能得到的最优解仍然小于ans,那么就可以剪枝。

  这可能就是所谓的最优化剪枝吧。

bubuko.com,布布扣
#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;
    }
}
View Code

 

UVa11882,Biggest Number,布布扣,bubuko.com

UVa11882,Biggest Number

标签:style   blog   http   color   os   io   for   art   

原文地址:http://www.cnblogs.com/bingolibing/p/3880512.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!