• 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;
    }

     

  • 相关阅读:
    java 连接SQL Server
    JAVA泛型
    JAVA 数组遍历
    JAVA注释
    Python正则表达式
    python练习题二
    Python函数
    Python练习题一
    重学python-列表的一些操作
    重学python-python-pandas库
  • 原文地址:https://www.cnblogs.com/dishu/p/4295040.html
Copyright © 2020-2023  润新知