DesertWind TopCoder - 1570 DP+搜索 hqg_ac

DesertWind D e s e r t W i n d TopCoder T o p C o d e r 1570

题意:有一张地图,”_”表示沙漠,”@”表示起点,”X”表示障碍物,”*”表示终点(终点可能有多个)

当你准备往一个格子进发时,你会知道当天的风向。如果你逆风走要3天,不逆风1天。

现在问你在最坏情况下最少要走多少天

Tc T c 的题的题面都很绕, minmax m i n m a x 层层套。。。

题解:

这个题目还是比较水的,关键在题意理解

你肯定尽可能最短路,控制风向的人肯定是让你的最短路径可能的长,好似一场博弈

这又是一道 DP D P 与图论(搜索)结合的题

dp[i][j] d p [ i ] [ j ] 表示到达 i,j i , j 的最坏天数

dp[i][j] d p [ i ] [ j ] 肯定从八个方向 (tx,ty) ( t x , t y ) 推得。

对于 dp[tx][ty] d p [ t x ] [ t y ] 中最小的,控制风向的人必定使得风向与之相反,而你肯定会走第二小的

于是 dp[i][j]=min(dp[i][j],max(dp[tx1][ty1]+3dp[tx2][ty2]+1) d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , m a x ( d p [ t x 1 ] [ t y 1 ] + 3 , d p [ t x 2 ] [ t y 2 ] + 1 )

dp[tx1][ty1] d p [ t x 1 ] [ t y 1 ] 是最小的, dp[tx2][ty2] d p [ t x 2 ] [ t y 2 ] 是第二小的

最后答案就是 dp[s][t] d p [ s ] [ t ]

#include <bits/stdc++.h>
using namespace std ;
const int N=100 ;
int dx[8]={-1,-1,-1,0,0,1,1,1} ;
int dy[8]={-1,0,1,-1,1,-1,0,1} ;
class DesertWind{
public:
    int n,m,s,t; 
    int dp[N][N],a[N][N],tmp[10] ;
    bool check(int x,int y){return (x>0 && y>0 && x<=n && y<=m) ;}
    int change(char c){
        if (c=='-') return 1 ;
        if (c=='X') return 2 ;
        if (c=='@') return 3 ;
        if (c=='*') return 4 ; 
    }
    int daysNeeded(vector <string> theMap){
        memset(dp,0x3f,sizeof(dp)); 
        n=theMap.size();m=theMap[1].size() ;
        for (int i=0;i<n;i++){
            for (int j=0;j<m;j++){
                a[i+1][j+1]=change(theMap[i][j]) ;
                if (theMap[i][j]=='*') dp[i+1][j+1]=0 ;
                else if (theMap[i][j]=='@') {
                    s=i+1;t=j+1;
                }
            }
        }
        for (int rnd=0;rnd<n*m;rnd++){
            for (int i=1;i<=n;i++){
                for (int j=1;j<=m;j++){
                    if (a[i][j]==2) { //障碍物 
                        continue ;
                    } 
                    int cnt=0;
                    for (int k=0;k<8;k++){
                        int tx=i+dx[k],ty=j+dy[k] ;
                        if (!check(tx,ty)) continue;
                        tmp[++cnt]=dp[tx][ty] ; 
                    }
                    sort(tmp+1,tmp+cnt+1) ;
                    dp[i][j]=min(dp[i][j],min(tmp[1]+3,tmp[2]+1)) ;
                }
            }
        }
        if (dp[s][t]==0x3f3f3f3f) return -1 ;
        else return dp[s][t] ;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值