1. 程式人生 > >【洛谷】【動態規劃(二維)】P1508 Likecloud-吃、吃、吃

【洛谷】【動態規劃(二維)】P1508 Likecloud-吃、吃、吃

方程 con == dash fine 自己 pan ans amp

【題目描述:】

正處在某一特定時期之中的李大水牛由於消化系統比較發達,最近一直處在饑餓的狀態中。某日上課,正當他餓得頭昏眼花之時,眼前突然閃現出了一個n*m(n and m<=200)的矩型的巨型大餐桌,而自己正處在這個大餐桌的一側的中點下邊。餐桌被劃分為了n*m個小方格,每一個方格中都有一個圓形的巨型大餐盤,上面盛滿了令李大水牛朝思暮想的食物。李大水牛已將餐桌上所有的食物按其所能提供的能量打了分(有些是負的,因為吃了要拉肚子),他決定從自己所處的位置吃到餐桌的另一側,但他吃東西有一個習慣——只吃自己前方或左前方或右前方的盤中的食物。

由於李大水牛已餓得不想動腦了,而他又想獲得最大的能量,因此,他將這個問題交給了你。

每組數據的出發點都是最後一行的中間位置的下方!

【輸入格式:】

第一行為m n.(n為奇數),李大水牛一開始在最後一行的中間的下方

接下來為m*n的數字距陣.

共有m行,每行n個數字.數字間用空格隔開.代表該格子上的盤中的食物所能提供的能量.

數字全是整數.

【輸出格式:】

一個數,為你所找出的最大能量值.

[算法分析:]

顯然是二維DP,設f[i][j]表示走到點(i, j)時的最大能量,a[i][j]表示點(i, j)的能量

則DP方程為:

  f[i][j] = max{f[i - 1][j - 1], f[i - 1][j], f[i - 1][j + 1]} + a[i][j]

有一(很)些(多)細節需要註意:

  1. 最後的答案並不是max{f[n][i]},因為李大水牛只能走到前方、左前方和右前方
  2. 保證讀入的列數m是奇數時,最中間的位置為[m / 2] + 1而不是[m / 2]

[Code:]

 1 //Likecloud-吃、吃、吃
 2 #include<iostream>
 3 #include<cstdio>
 4 #define re register
 5 using namespace std;
 6 
 7 const int MAXN = 200 + 1;
 8 
 9 int n, m, ans;
10 int a[MAXN][MAXN]; 11 int f[MAXN][MAXN]; 12 13 inline int read() { 14 int x=0, f=1; char ch=getchar(); 15 while(ch<0 || ch>9) { 16 if(ch == -) f = -1; 17 ch = getchar(); 18 } 19 while(ch>=0 && ch<=9) 20 x=(x<<3) + (x<<1) + ch-48, ch = getchar(); 21 return x * f; 22 } 23 24 inline int Max(int a, int b, int c) { 25 return max(max(a, b), c); 26 } 27 28 int main() { 29 n = read(), m = read(); 30 for(re int i=1; i<=n; ++i) 31 for(re int j=1; j<=m; ++j) 32 a[i][j] = read(); 33 for(re int i=1; i<=m; ++i) f[1][i] = a[1][i]; 34 for(re int i=2; i<=n; ++i) 35 for(re int j=1; j<=m; ++j) 36 f[i][j] = Max(f[i - 1][j - 1], f[i - 1][j], f[i - 1][j + 1]) + a[i][j]; 37 int ans = Max(f[n][m / 2 + 1], f[n][(m / 2)], f[n][(m / 2) + 2]); 38 printf("%d\n", ans); 39 }

【洛谷】【動態規劃(二維)】P1508 Likecloud-吃、吃、吃