zoukankan      html  css  js  c++  java
  • ZZULIOJ 1875: 蛤玮的财宝(三维DP)

    郑州轻工业大学“玲珑杯ACM程序设计比赛”第二题

    官方题解:

    由于只能往下往右走,所以两条路径的长度是一样的,用dp[l][i][j]表示两个人都走了l步,第一个人在第i行,第二个人在第j行所能得到的最大值,两个人分别往下或往右走一步,有四种转移,如果走到了相同点则权值只加一个.

    比赛时搞了好久也没搞出来,看了题解后做了一下。AC后对比标准程序,发现比标程简洁些:)

    标程是对当前状态,计算后面四个状态;而我的代码是从前面四个状态,计算当前状态。

    #include "algorithm"
    #include "iostream"
    #include "cstring"
    #include "cstdio"
    #include "string"
    #include "stack"
    #include "cmath"
    #include "queue"
    #include "set"
    #include "map"
    typedef long long ll;
    using namespace std;
    
    const int inf=0x3f3f3f3f;
    const int maxn=100+5;
    
    int t,m,n;
    int mp[maxn][maxn];
    int dp[250][250][250];
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            int sum=0;
            for(int i=1; i<=n; ++i)
            {
                for(int j=1; j<=m; ++j)
                {
                    cin>>mp[i][j];
                    sum+=mp[i][j];
                }
            }
            if( n<=2 || m<=2 )
            {
                cout<<sum<<endl;
                continue;
            }
            memset(dp,0,sizeof dp);
    
            dp[0][1][1]=mp[1][1];
            for(int k=1; k<=m+n-2; ++k)
            {
                for(int i1=1; i1<=n ; ++i1)
                {
                    for(int i2=1; i2<=n; ++i2)
                    {
    
                        int tmp = dp[k-1][i1][i2];
                        if(i2>1)tmp = max( tmp,dp[k-1][i1][i2-1] );
                        if(i1>1)tmp = max( tmp,dp[k-1][i1-1][i2] );
                        if(i1>1 && i2>1)tmp = max( tmp,dp[k-1][i1-1][i2-1] );
    
                        //如果两人走到了同一个位置
                        if(i1==i2)
                        {
                            dp[k][i1][i2] += tmp + mp[i1][k+2-i1];
                        }
                        else
                        {
                            dp[k][i1][i2] += tmp + mp[i1][k+2-i1] + mp[i2][k+2-i2];
                        }
                    }
                }
            }
            cout<<dp[m+n-2][n][n]<<endl;
        }
    
    }
    

      

  • 相关阅读:
    HashMap按键排序和按值排序
    LeetCode 91. Decode Ways
    LeetCode 459. Repeated Substring Pattern
    JVM
    LeetCode 385. Mini Parse
    LeetCode 319. Bulb Switcher
    LeetCode 343. Integer Break
    LeetCode 397. Integer Replacement
    LeetCode 3. Longest Substring Without Repeating Characters
    linux-网络数据包抓取-tcpdump
  • 原文地址:https://www.cnblogs.com/bruce27/p/5421658.html
Copyright © 2011-2022 走看看