首页 > 其他 > 详细

洛谷专题-多维DP

时间:2020-02-20 15:07:35      阅读:86      评论:0      收藏:0      [点我收藏+]

P1004方格取数(四维DP模板题)

题意:

一个矩阵,A从左上角走到右下角,B从右下角走到最下角问AB走过的路径和最大是多少,一个点只能被计算一次

思路:

定义dp[i][j][k][l]为A走到(i , j) B走到 (k , l) 的最大值

那么状态转移方程就为dp[i][j][k][l]=max( dp[i1][j][k1][l, dp[i1][j][k][l1, dp[i][j1][k1][l], dp[i][j1][k][l1]a[i][ja[k][l]

还需注意的是当 i==k && j==l时要减去一次a[i][j]的值,因此重复走一个点只能算一次

技术分享图片
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
 using namespace std;
 const int maxn=10;
 int a[maxn][maxn],dp[maxn][maxn][maxn][maxn];
 int main()
 {
     int n,x,y,c;
     scanf("%d",&n);
     while(scanf("%d%d%d",&x,&y,&c)&&x&&y&&c)
         a[x][y]=c;
     memset(dp,0,sizeof(0));
     for(int i=1;i<=n;i++){
         for(int j=1;j<=n;j++){
             for(int k=1;k<=n;k++){
                 for(int l=1;l<=n;l++){
                     dp[i][j][k][l]=max(dp[i-1][j][k-1][l],max(dp[i][j-1][k-1][l],max(dp[i-1][j][k][l-1],
                     dp[i][j-1][k][l-1])))+a[i][j]+a[k][l];
                     if(i==k&&j==l) dp[i][j][k][l]-=a[i][j];
                 }
             }
         }
     }
    cout<<dp[n][n][n][n]<<endl;
  } 
View Code

当然还可以降到三维dp[i][j][k]表示走了i步,A走到j行,B走到k行

那么转移方程式为max(dp[i-1][j][k] , dp[i-1][j-1][k-1] , dp[i-1][j-1][k] , dp[i-1][j][k-1])

仍要记得去重

 

技术分享图片
#include<stdio.h>
using namespace std;
int n;int map[9][9];
int d[18][9][9];int res;           
int max(int a,int b,int c,int d)
{
 return (((((a>b)?a:b)>c)?((a>b)?a:b):c)>d)?((((a>b)?a:b)>c)?((a>b)?a:b):c):d;
}
 int main()
 {
    scanf("%d",&n);
    while (1)
    {
        int x;int y;int val;
        scanf("%d%d%d",&x,&y,&val);
        if(x==0&&y==0&&val==0)break;
        map[x-1][y-1]=val;
   }
   d[0][0][0]=map[0][0];
   for(int i=0;i<2*n;i++){
        for(int j=0;j<=i&&j<n;j++){
            for(int k=0;k<=i&&k<n;k++){
                if(i==0&&j==0&&k==0)continue;
                d[i][j][k]=map[j][i-j]+map[k][i-k]+
                           max(d[i-1][j][k],d[i-1][j-1][k-1],d[i-1][j-1][k],d[i-1][j][k-1]);
                if(j==k)d[i][j][k]-=map[j][i-j];         
            }
        }
    }
    res=d[2*(n-1)][n-1][n-1];
    printf("%d",res);
    return 0;
}
View Code

 

洛谷专题-多维DP

原文:https://www.cnblogs.com/overrate-wsj/p/12335362.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!