行军

题目链接

首先这里有两个动点,一个是军队,另一个是敌人

因为敌人的移动比较机械,所以我们考虑只用己方的状态来表示。

随着时间推移,每个敌军都会移动,那么我们直接加上敌军移动的一格,往下多走一格,就可以实现相对运动

化动为静

设F[i][j]表示我军走到(i,j)这个方格需要的最小步数,那么有三种情况

  1. 直接往下走继承而来,那么如果这一格或上一格有敌军,就可以++
  2. 从左上角继承而来,变成(i-2,j-1),继承而来,如果碰到这一个有敌军,就++人数
  3. 从右上角继承而来,同理
#include<bits/stdc++.h>
#define min(a,b) (a<b?a:b)
using namespace std;
int l,k;
int s[105][105],f[105][105];
char c;
int main(){
    freopen("march.in","r",stdin);
    freopen("march.out","w",stdout);
    scanf("%d%d",&l,&k);
    for(int i=l;i>=1;--i)//为了便于处理,倒着输入
     for(int j=1;j<=k;++j){
         cin>>c;
         s[i][j]=c-48;
         f[i][j]=1e9;
     }
    for(int i=2;i<=l;i+=2)
     for(int j=1;j<=k;++j){
         f[i][j]=min(f[i][j],f[i-2][j]+s[i-1][j]+s[i][j]);//加上这一格和上一格1
         if(j<k)f[i][j]=min(f[i][j],f[i-2][j+1]+s[i][j]);//加上这一格2
         if(j>1)f[i][j]=min(f[i][j],f[i-2][j-1]+s[i][j]);//加上这一格3
     }
    int ans=1e9;
    for(int i=1;i<=k;++i)ans=min(ans,f[l][i]);//在最后一排取最小
    cout<<ans;
}
原文地址:https://www.cnblogs.com/coder-cjh/p/11628429.html