HDU 1176 免费馅饼 矩阵取数, dp + 滚动数组

http://acm.hdu.edu.cn/showproblem.php?pid=1176

首先可以处理出整张地图的状态。

book[T][POS]表示第T秒,在第pos个地方有多少个馅饼。

dp[i][j]表示第i秒的时候,在第j个位置能得到的最大值。

边界值:dp[1][4] = book[1][4];  dp[1][5] = book[1][5]; dp[1][6] = book[1][6];

因为一开始一步只能走到这里。

然后转移枚举下一秒的时候,由上面的状态选一个最大的枚举下来。

因为只和上一唯有关,所以可以用滚动数组来实现。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e5 + 20;
int n;
int book[maxn][12];
int dp[2][12];
void work() {
    memset(book, 0, sizeof book);
    memset(dp, 0, sizeof dp);
    int mx = -inf;
    for (int i = 1; i <= n; ++i) {
        int T, pos;
        scanf("%d%d", &pos, &T);
        book[T][pos]++;
        mx = max(mx, T);
    }
    dp[1][5] = book[1][5];
    dp[1][4] = book[1][4];
    dp[1][6] = book[1][6];
    int now = 0;
    for (int i = 2; i <= mx; ++i) {
        for (int j = 0; j <= 10; ++j) {
            if (j == 0) {
                dp[now][j] = max(dp[!now][j], dp[!now][j + 1]) + book[i][j];
            } else if (j == 10) {
                dp[now][j] = max(dp[!now][j - 1], dp[!now][j]) + book[i][j];
            } else {
                dp[now][j] = max(dp[!now][j - 1], max(dp[!now][j], dp[!now][j + 1])) + book[i][j];
            }
        }
        now = !now;
    }
    int ans = -inf;
    for (int i = 0; i <= 10; ++i) ans = max(ans, dp[!now][i]);
    printf("%d
", ans);
}

int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    while (scanf("%d", &n) && n) work();
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6003782.html