HAF1 - Đua Xe

Tags: dp

Problem

https://vn.spoj.com/problems/HAF1

https://oj.vnoi.info/problem/HAF1

Cuộc đua F1 năm 2009 thay bằng việc đua nhiều vòng vào các thời điểm khác nhau thể lại đua luôn nhiều vòng 1 lần. (Tuy nhiên mỗi vòng lại có nhiều đường đua, mỗi đường có chiều dài khác nhau chỉ số khác nhau,nối với 1 đường cùng chỉ số ở vòng tiếp theo)Đặc biệt mỗi xe chỉ cần chạy 1 số đường ở mỗi vòng và sang vòng đua tiếp theo.Tuy nhiên vì là cuộc đua F1 tầm cỡ thế giới nên ở các góc đường đều có bom(>_<)nên không thể chạy chéo được mà chỉ có thể chạy thẳng hoặc chạy sang ngang mà thôi.

Bạn hăy tìm ra con đường ngắn nhất đi từ vòng 1 đến vòng cuối để giúp các tay đua dễ dàng trở thành nhà vô địch.

Lưu ý:Vì cuộc đua F1 là đua xe ô tô nên các xe sẽ không thể bay được(nhảy cóc)mà chỉ có thể chạy trên các đoạn đường kề nhau.

Input

  • Gồm một dòng duy nhất chứa 2 số N,M(số đường đua mỗi vòng,số vòng đua).
  • M dòng tiếp mỗi dòng N số là chiều dài của đường đua.

Output

  • 1 dòng duy nhất là độ dài đường đi ngắn nhất.

Giới hạn

  • 0 < M(số vòng đua) <=1000.
  • 0 < N(số đường đua ở mỗi vòng)<=1000.
  • 0 < a(chiều dài mỗi đường đua)<=1000

Ví dụ

Input
3 3
3 2 1
4 1 1
8 1 3

Output
4

Tutorial


Submission

HAF1.cpp
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> ii;
typedef unsigned long long ull;

#define X first
#define Y second
#define pb push_back
#define mp make_pair
#define ep emplace_back
#define EL printf("\n")
#define sz(A) (int) A.size()
#define FOR(i,l,r) for (int i=l;i<=r;i++)
#define FOD(i,r,l) for (int i=r;i>=l;i--)
#define fillchar(a,x) memset(a, x, sizeof (a))
#define faster ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);


const int N = 1001, inf = 2e9;
int n, m, a[N], ans, F[2][N][4];



int main() {
//  freopen("INP.TXT", "r", stdin);
//  freopen("OUT.TXT", "w", stdout);


	scanf("%d%d", &n,&m);

	FOR(i,1,m) {
		FOR(j,1,n) {
			scanf("%d", &a[j]);
			FOR(t,0,3) F[0][j][t] = F[1][j][t];
			F[1][j][2] = a[j] + F[0][j][3];
			if (j == 1)
				F[1][j][0] = inf;
			else
				F[1][j][0] = a[j] + min(F[1][j-1][0], F[1][j-1][2]);
		}
		FOD(j,n,1) {
			if (j == n)
				F[1][j][1] = inf;
			else
				F[1][j][1] = a[j] + min(F[1][j+1][1], F[1][j+1][2]);
			F[1][j][3] = min(min(F[1][j][0], F[1][j][1]), F[1][j][2]);
		}
	}

	int ans = inf;
	FOR(j,1,n) ans = min(ans, F[1][j][3]);

	printf("%d\n", ans);


	return 0;
}