HDU 1650&&3533 【IDA*和A*】

HDU 1650&&3533 【IDA * 和A*】

引子:先说一下IDA* 和A*的内容以及用法。
估价函数:
估价函数假设用h(x)表示,到达目前状态的代价用g(x)表示,那么估计的完成代价为f(x)=g(x)+h(x)。如果f(x)大于题目所需,那么可以进行剪枝。

需要注意的是,h(x)必须小于等于实际最优代价,满足此条件下越接近实际代价该估价函数越优。
A *算法是什么?它是启发式搜索的一种,即广度搜索算法bfs加上估价函数。(八数码||K短路)

而IDA*则是另一种类似的启发式搜索,是迭代加深dfs加上估价函数。
下面两个基础板子题目:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char mp[9][5];
int n,len[9],pos[9],vis[9],maxlen;
char a[5]="ACGT";
int dfs(int dep)
{
    
    
    int ma=0;
    for(int i=1; i<=n; i++)
    {
    
    
        ma=max(len[i]-pos[i],ma);
    }
    if(ma==0)
        return 1;
    if(ma+dep>maxlen)///估值优化
        return 0;
    int vis[10];
    for(int i=0; i<4; i++)
    {
    
    
        memset(vis,0,sizeof vis);
        for(int j=1; j<=n; j++)
        {
    
    
            if(mp[j][pos[j]]==a[i])
            {
    
    
                vis[j]=1;
                pos[j]++;
            }
        }
        if(dfs(dep+1))
            return 1;
        for(int j=1; j<=n; j++)///回溯
        {
    
    
            if(vis[j])
            {
    
    
                pos[j]--;
            }
        }
    }
    return 0;
}

int main()
{
    
    
    int t ;
    scanf("%d",&t);
    while(t--)
    {
    
    
        scanf("%d",&n);
        maxlen=1;
        for(int i=1; i<=n; i++)
        {
    
    
            scanf("%s",mp[i]);
            len[i]=strlen(mp[i]);
            maxlen=max(maxlen,len[i]);
            pos[i]=0;
        }
        while(maxlen)///迭代加深
        {
    
    
            memset(pos,0,sizeof pos);
            if(dfs(0))
            {
    
    
                break;
            }
            maxlen++;
        }
        printf("%d\n",maxlen);
    }
}
#include<bits/stdc++.h>
using namespace std;
int n,m,k,d,odk;
const int maxn=105;
bool mp[maxn][maxn],ok[maxn][maxn][2];
bool vis[105][105][1005];
int dir[4][2]= {
    
    {
    
    0,1},{
    
    0,-1},{
    
    -1,0},{
    
    1,0}};
struct node
{
    
    
    int t,v,x,y,dir;
} p[maxn],pp[maxn];
struct nod
{
    
    
    int x,y,step,flag,g,h;
    bool operator<(const nod &a)const
    {
    
    
        return a.h<h;
    }
};
bool cmp1(node a,node b)
{
    
    
    if(a.y!=b.y)
        return a.y<b.y;
    return a.x<b.x;
}
bool cmp2(node a,node b)
{
    
    
    if(a.x!=b.x)
        return a.x<b.x;
    return a.y<b.y;

}
priority_queue<nod>q;///优化之后优先队列维护
int bfs()
{
    
    
    while(!q.empty())q.pop();
    q.push({
    
    0,0,0,1});
    vis[0][0][0]=1;
    while(!q.empty())
    {
    
    
        nod f=q.top(),v;
        q.pop();
        if(f.step>d)
           return 0;
        if(f.x==m&&f.y==n)
        {
    
    
            odk=f.step;
            return f.step<=d;
        }
        for(int i=0; i<4; i++)
        {
    
    
            v.x=dir[i][0]+f.x;
            v.y=dir[i][1]+f.y;
            v.flag=1,v.step=f.step+1,v.g=abs(v.x-n)+abs(v.y-n),v.h=v.step+v.g;///估值优化
            if(v.x<0||v.x>m||v.y<0||v.y>n||mp[v.x][v.y]||vis[v.x][v.y][v.step]||ok[v.x][v.y][v.flag])
                continue;
            vis[v.x][v.y][v.step]=1,ok[v.x][v.y][v.flag]=1;
            q.push(v);
        }
        v=f;
        if(f.flag)
        {
    
    
            v.flag=0,v.step=f.step+1,v.g=abs(v.x-n)+abs(v.y-n),v.h=v.step+v.g;
            if(v.x<0||v.x>m||v.y<0||v.y>n||mp[v.x][v.y]||vis[v.x][v.y][v.step]||ok[v.x][v.y][v.flag])
                continue;
            vis[v.x][v.y][v.step]=1,ok[v.x][v.y][v.flag]=1;
            q.push(v);
        }
    }
    return 0;
}
int main()
{
    
    
    while(~scanf("%d%d%d%d",&m,&n,&k,&d))
    {
    
    
        memset(vis,0,sizeof vis);
        memset(mp,0,sizeof mp);
        memset(ok,0,sizeof ok);
        int cnt1=1,cnt2=1;
        char c;
        for(int i=1; i<=k; i++)
        {
    
    
            cin>>c;
            if(c=='N'||c=='S')///N=1,S=2;
            {
    
    
                scanf("%d%d%d%d",&p[cnt1].t,&p[cnt1].v,&p[cnt1].x,&p[cnt1].y);
                if(c=='N')
                    p[cnt1].dir=1;
                else
                    p[cnt1].dir=2;
                cnt1++;
            }
            else///W=3,E=4;
            {
    
    
                scanf("%d%d%d%d",&pp[cnt2].t,&pp[cnt2].v,&pp[cnt2].x,&pp[cnt2].y);
                if(c=='W')
                    pp[cnt2].dir=3;
                else
                    pp[cnt2].dir=4;
                cnt2++;
            }
        }
        //cout<<cnt2<<endl;
        //
        sort(p+1,p+cnt1,cmp1);
        sort(pp+1,pp+cnt2,cmp2);
        int dir,x,y,t,v;

        for(int i=1; i<cnt1; i++)
        {
    
    
            for(int k=1; k<=d; k++)
            {
    
    
                if(k==1)
                    dir=p[i].dir,x=p[i].x,y=p[i].y,t=p[i].t,v=p[i].v,mp[x][y]=1;
                if(p[i].dir==1)
                {
    
    
                    x=p[i].x-k*v;
                    if(x<0||x>n||y<0||y>m||(y==p[i-1].y&&x<=p[i-1].x))
                        break;
                    /// cout<<x<<" "<<y<<" "<<k<<endl;
                    vis[x][y][k]=1;
                    for(int j=k+t; j<=d; j+=t)
                        vis[x][y][j]=1;
                }
                else
                {
    
    
                    x=p[i].x+k*v;
                    if(x<0||x>n||y<0||y>m||(y==p[i+1].y&&x>=p[i+1].x))
                        break;
                    /// cout<<x<<" "<<y<<" "<<k<<endl;
                    vis[x][y][k]=1;
                    for(int j=k+t; j<=d; j+=t)
                        vis[x][y][j]=1;
                }
            }
        }
        for(int i=1; i<cnt2; i++)
        {
    
    
            for(int k=1; k<=d; k++)
            {
    
    
                if(k==1)
                    dir=pp[i].dir,x=pp[i].x,y=pp[i].y,t=pp[i].t,v=pp[i].v,mp[x][y]=1;;
                if(pp[i].dir==3)
                {
    
    
                    y=pp[i].y-k*v;
                    if(x<0||x>n||y<0||y>m||(x==pp[i-1].x&&y<=pp[i-1].y))
                        break;
                    ///cout<<x<<"*"<<y<<" "<<k<<endl;
                    vis[x][y][k]=1;
                    for(int j=k+t; j<=d; j+=t)
                        vis[x][y][j]=1;
                }
                else
                {
    
    
                    y=pp[i].y+k*v;
                    if(x<0||x>n||y<0||y>m||(x==pp[i+1].x&&y>=pp[i+1].y))
                        break;
                    /// cout<<x<<" "<<y<<" "<<k<<endl;
                    vis[x][y][k]=1;
                    for(int j=k+t; j<=d; j+=t)
                        vis[x][y][j]=1;
                }
            }
        }
        int ans=bfs();
        if(ans==0)
            puts("Bad luck!");
        else
            cout<<odk<<endl;
    }


}
/*
4 4 3 10
N 1 1 1 1
W 1 1 3 2
W 2 1 2 4


4 4 3 10
N 1 1 1 1
W 1 1 3 2
W 1 1 2 4


*/

猜你喜欢

转载自blog.csdn.net/qq_43653111/article/details/103132588