寝癖頭の解法

小学生の目線から、勉強中の覚え書きを投稿、更新していきます。

AtCoder Problems in C++ #E - 森林伐採(Deforestation)

JOI 2017/2018 予選 過去問から、その提出コードの解答例です。
AtCoderとは、コンテストを通じて、プログラミングやアルゴリズムを学習するサービスです。
atcoder.jp
プログラミングコンテストとは、「与えられた問題をいかに素早く、正確に」解くことができるかを競うものです。
競技プログラミング」を略して、「競プロ」などと呼ばれています。

#E - 森林伐採(Deforestation)

atcoder.jp

僕が作成、提出したコードは、以下のとおりです。

/*
AtCoder Problems in C++
#E - 森林伐採(Deforestation)
https://atcoder.jp/contests/joi2018yo/tasks/joi2018_yo_e
提出コードの解答例
https://neguse-atama.hatenablog.com
*/
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
int main(void){
  ll h,w;
  cin>>h>>w;
  vector<vector<ll>> a(h,vector<ll>(w));
  for(ll i=0;i<h;i++){
    for(ll j=0;j<w;j++){
      cin>>a[i][j];
    }
  }
  const ll dy[4]={1,-1,0,0};
  const ll dx[4]={0,0,1,-1};
  const ll inf=10000000000;
  vector<vector<vector<ll>>> dp(h*w,vector<vector<ll>>(h,vector<ll>(w,inf)));
  dp[0][0][0]=0;
  for(ll k=0;k<h*w-1;k++){
    for(ll i=0;i<h;i++){
      for(ll j=0;j<w;j++){
        for(ll l=0;l<4;l++){
          ll y=i+dy[l];
          ll x=j+dx[l];
          if(y<0 || y>=h || x<0 || x>=w){
            continue;
          }
          ll c=dp[k][i][j]+a[y][x]*(k*2+1);
          dp[k+1][y][x]=min(dp[k+1][y][x],c);
        }
      }
    }
  }
  ll ans=inf;
  for(ll i=0;i<h*w;i++){
    ans=min(ans,dp[i][h-1][w-1]);
  }
  cout<<ans<<endl;
  return 0;
}