P1006 传纸条 & P1004 方格取数(四维dp)

四维dp:状态太多就多开数组。

P1004

题目链接:https://www.luogu.com.cn/problem/P1004

思路:

因为有两条路径,他们之间相互影响,如果走到相同的地点只算一次aij。

状态转移方程:dp(i,j,p,q) = max { dp(i-1,j,p-1,q) , dp(i-1,j,p,q-1) , dp(i,j-1,p-1,q) , dp(i,j-1,p,q-1) } + a[i][j] + a[p][q];

如果i == p && j == q,dp(i,j,p,q) = max { dp(i-1,j,p-1,q) , dp(i-1,j,p,q-1) , dp(i,j-1,p-1,q) , dp(i,j-1,p,q-1) } + a[i][j] ;

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[12][12] = {0},dp[12][12][12][12] = {0};
ll Max(ll x,ll y,ll z,ll d)
{
    return max(max(x,y),max(z,d));
}
int main(void)
{
    int n,x,y,z;
    scanf("%d",&n);
    while(~scanf("%d%d%d",&x,&y,&z))
    {
        if(x == 0 && y == 0 && z == 0) break;
        a[x][y] = z;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            for(int p=1;p<=n;p++)
            {
                for(int q=1;q<=n;q++)
                {
                    if(i == p && j == q)
                    {
                        dp[i][j][p][q] = Max(dp[i-1][j][p-1][q],dp[i-1][j][p][q-1],
                                             dp[i][j-1][p-1][q],dp[i][j-1][p][q-1]) + a[i][j];
                    }
                    else{
                        dp[i][j][p][q] = Max(dp[i-1][j][p-1][q],dp[i-1][j][p][q-1],
                                             dp[i][j-1][p-1][q],dp[i][j-1][p][q-1])
                                             + a[i][j] + a[p][q];
                    }
                }
            }
        }
    }
    printf("%lld\n",dp[n][n][n][n]);
    return 0;
}

P1006

题目链接:https://www.luogu.com.cn/problem/P1006

思路:

与上面的题目类似,有两条路径s1->sn,sn->s1,如果第一条路径走过了aij,第二条路径就不能记录aij的值,

其实就是上面那题,把数据变大了。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[52][52] = {0},dp[52][52][52][52] = {0};
ll Max(ll x,ll y,ll z,ll d)
{
    return max(max(x,y),max(z,d));
}
int main(void)
{
    int n,m,x,y,z;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) scanf("%lld",&a[i][j]);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            for(int p=1;p<=n;p++)
            {
                for(int q=1;q<=m;q++)
                {
                    if(i == p && j == q)
                    {
                        dp[i][j][p][q] = Max(dp[i-1][j][p-1][q],dp[i-1][j][p][q-1],
                                             dp[i][j-1][p-1][q],dp[i][j-1][p][q-1]) + a[i][j];
                    }
                    else{
                        dp[i][j][p][q] = Max(dp[i-1][j][p-1][q],dp[i-1][j][p][q-1],
                                             dp[i][j-1][p-1][q],dp[i][j-1][p][q-1])
                                             + a[i][j] + a[p][q];
                    }
                }
            }
        }
    }
    printf("%lld\n",dp[n][m][n][m]);
    return 0;
}
发布了438 篇原创文章 · 获赞 16 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/103758654
今日推荐