洛谷-P1508 Likecloud-喫、喫、喫

題目背景

問世間,青春期爲何物?

答曰:“甲亢,甲亢,再甲亢;捱餓,捱餓,再捱餓!”

題目描述

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

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

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

輸入輸出格式

輸入格式:

[輸入數據:]

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

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

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

數字全是整數.

輸出格式:

[輸出數據:]

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

輸入輸出樣例

輸入樣例#1: 複製

6 7
16 4 3 12 6 0 3
4 -5 6 7 0 0 2
6 0 -1 -2 3 6 8
5 3 4 0 0 -2 7
-1 7 4 0 7 -5 6
0 -1 3 4 12 4 2

輸出樣例#1: 複製

41

說明

快喫!快喫!快喫!

 

這個題目的狀態轉移方案很容易想到, 一層一層遍歷的話, 上一層的狀態只能由下一層的左下, 下, 右下三個位置得到

所以有dp[i][j] = max( dp[i][j], mp[i][j]+(dp[i+1][j-1] , dp[i+1][j] , dp[i+1][j+1]) );

初始化最後n+1那一排爲負無窮, 這樣就可以了

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int INF = -12345689;
int n,m;
int mp[205][205];
int dp[205][205];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            scanf("%d",&mp[i][j]);
        }
    for(int i=1;i<=m;i++)
        dp[n+1][i] = INF;
    dp[n+1][(m>>1)+1] = 0;
    for(int i=n;i>=1;i--){
        for(int j=1;j<=m;j++){
            dp[i][j] = mp[i][j]+dp[i+1][j];
            if(j-1> 0) dp[i][j] = max(dp[i][j],mp[i][j]+dp[i+1][j-1]);
            if(j+1<=m) dp[i][j] = max(dp[i][j],mp[i][j]+dp[i+1][j+1]);
        }
    }
    int tp = dp[1][1];
    for(int i=1;i<=n;i++){
        tp = max(tp,dp[1][i]);
    }
    cout<<tp<<endl;
    return 0;
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章