BUPT 202 Chocolate Machine 动态规划

2011年的北邮多校联合赛H题

BUPT 202 chocolate mashine

学校的老OJ要挂代理才能上 所以这里给一个hust上的题目链接:

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70168#problem/J

 

均从1开始计数

dp[i][j]表示以第i行第j列小格为巧克力最右下角时 金钱的最大值

视值小于K的小格为“阻挡”

若(i, j)本身为“阻挡” 则dp[i][j] = 0

若(i, j)的上面一格和左边一格均有“阻挡” 则dp[i][j] = a[i][j]

若仅上面一格为“阻挡” 则 dp[i][j] = 从当前格开始往左边加 直到遇到边界或“阻挡”

若仅左边一格为“阻挡” 则 dp[i][j] = 从当前格开始往上面加 直到遇到边界或“阻挡”

若上和左均无阻挡  则dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + a[i][j]

 

然后不断更新dp[i][j]中的最大值

 

不难 就是按我这个思路走的话比较繁琐 wa了4炮TAT

 

 

 

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <stack>
#include <set>
#include <queue>
#include <vector>

using namespace std;

typedef long long ll;

const int maxn = 3010;

ll dp[maxn][maxn];
int a[maxn][maxn];

int main()
{
    //freopen("in.txt", "r", stdin);

    int T;
    scanf("%d", &T);
    while(T--)
    {
        int n, m, k;
        scanf("%d%d%d", &n, &m, &k);

        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
                scanf("%d", &a[i][j]);

        ll ans = 0;

        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
            {
                if(a[i][j] < k)
                    dp[i][j] = 0;
                else
                {
                    if(dp[i-1][j] == 0 && dp[i][j-1] == 0)
                        dp[i][j] = a[i][j];
                    else if(i-1 >= 1 && dp[i-1][j] == 0)
                    {
                        dp[i][j] = a[i][j];
                        int t = 1;
                        while(j - t >= 1 && dp[i][j-t] != 0)
                        {
                            dp[i][j] += a[i][j-t];
                            t++;
                        }
                    }
                    else if(j - 1 >= 1 && dp[i][j-1] == 0)
                    {
                        dp[i][j] = a[i][j];
                        int t = 1;
                        while(i - t >= 1 && dp[i-t][j] != 0)
                        {
                            dp[i][j] += a[i-t][j];
                            t++;
                        }
                    }
                    else
                    {
                        dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-1] + a[i][j];
                    }
                }

                if(dp[i][j] > ans)
                    ans = dp[i][j];
            }

        printf("%I64d
", ans);
    }

    return 0;
}

 

原文地址:https://www.cnblogs.com/dishu/p/4295040.html