• [USACO17FEB]Why Did the Cow Cross the Road I G


    一开始想写$DP$,发现直接转移完全有后效性

    所以本小蒟蒻写了个最短路

    每走三步就要吃草是这个题最难搞的地方,我们建图时不妨只对于距离等于三的点连边

    考虑完全覆盖所有情况,从一个点走一步,两步,然后三步,和直接走三步代价是等价的

    这样从每个点到与其曼哈顿距离为三的所有点连边即可

    考虑到终点的答案,对于所有小于三步到终点的位置到终点的代价,找到最小值即为答案

    有个坑就是比如右左右这种走法,我们也需要从一个点向其周围的点连边

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define int long long
    using namespace std;
    const int maxn=20010;
    struct edge{
        int next,to,dis;
    }e[12*maxn];
    int n,t,g[110][110],len[maxn],head[maxn],cnt,ans=1e9;
    int dx[]={-1,-2,-3,-1,-2,0,1,2,1,2,3,0,0,1,0,-1};
    int dy[]={-2,-1,0,2,1,-3,-2,-1,2,1,0,3,1,0,-1,0};
    bool exist[maxn];
    inline void add(int x,int y,int d)
    {
        e[++cnt].next=head[x];
        e[cnt].to=y;
        e[cnt].dis=d;
        head[x]=cnt;
    }
    inline int make(int x,int y)
    {
        return x*n+y;
    }
    int dijkstra()
    {
        priority_queue<pair<int,int> >q;
        memset(len,0x3f,sizeof(len));
        q.push(make_pair(0,make(1,1)));
        len[make(1,1)]=0;
        while(!q.empty())
        {
            int u=q.top().second;
            q.pop();
            if(exist[u])
                continue;
            exist[u]=1;
            for(int v,i=head[u];i;i=e[i].next)
                if(len[v=e[i].to]>len[u]+e[i].dis)
                {
                    len[v]=len[u]+e[i].dis;
                    q.push(make_pair(-len[v],v));
                }
        }
    }
    void check(int x,int y)
    {
        for(int i=0;i<16;i++)
            if(x+dx[i]>0&&x+dx[i]<=n&&y+dy[i]>0&&y+dy[i]<=n)
                add(make(x,y),make(x+dx[i],y+dy[i]),3*t+g[x+dx[i]][y+dy[i]]);
    }
    signed main()
    {
        scanf("%lld%lld",&n,&t);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                scanf("%lld",&g[i][j]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                check(i,j);
        dijkstra();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(2*n-i-j<3)
                    ans=min(ans,len[make(i,j)]+(2*n-i-j)*t);
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    jquery面试(2)
    jquery面试题
    javascript面试题(2)
    javascript--面试题
    遇到的问题:
    artTemplate的使用案列
    CSS3 background-size 属性
    listandset实例
    testng.xml
    sts设置Code Templates
  • 原文地址:https://www.cnblogs.com/ivanovcraft/p/9754397.html
Copyright © 2020-2023  润新知