• 多维dp


    P1006 传纸条 我的第一道多维dp

    我第一眼看到这道题 就知道不会 因为从来没见过 

    后来看了神仙的题解 恍然大悟 然而自己写的时候还是有bug(逃

    这里给出一个三维数组的解法(oi爷太强了

    首先,要找来回两条路径,这样考虑太麻烦,把它转化为两个人从1,1这点一起走,一直走到n,m这点所经过的路径。

    定义dp[p][i][j]表示当前走了p步,第一个人走到第i行,第二个人走到第j行的最大价值。

    显然两个人的坐标都可以计算出来,第一个人是(i,p-i+1),第二个人是(j,p-j+1).

    那么状态转移方程呼之欲出 就是

    dp[p][i][j]=max(dp[p-1][i][j],dp[p-1][i-1][j],dp[p-1][i-1][j-1],dp[p-1][i][j-1])+num[i][p-i+1]+num[j][p-j+1];

    不要以为到这就结束了!

    在循环时 我们一定要判断!!

    判断什么呢 当i=j时 代表他们坐标重复了(想想为什么   所以这时候 价值只能算i j其中一个的

    还有一点! 循环时 双层循环全部要到m 而不是一个n一个m  因为这里的 i j 全部代表层数 

    还有一点(我wa掉的一点   就是双层for不仅要判断层数小于m 而且要判断当前步数小于总步数

    要不然会wa掉第二个点(逃

    接下来 放代码

    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #include <stdio.h>
    #include <iostream>
    using namespace std;
    const int e=55;
    int dp[2*e][e][e],num[e][e];
    int n,m;
    int maxx(int a,int b,int c,int d)
    {
    	if(a<b)
    		a=b;
    	if(c>a)
    		a=c;
    	if(d>a)
    		a=d;
    	return a;
    }
    int main(int argc, char const *argv[])
    {
    	cin >> m >> n;
    	rep(i,1,m){
    		rep(j,1,n){
    			cin >> num[i][j];
    		}
    	}
    	dp[1][1][1]=num[1][1];
    	rep(p,2,n+m-1){
    		for(int i=1;i<=m&&i<=p;i++){
    			for(int j=1;j<=m&&j<=p;j++){
    				dp[p][i][j]=maxx(dp[p-1][i][j],dp[p-1][i-1][j-1],dp[p-1][i][j-1],dp[p-1][i-1][j]);
    				int sum;
    				if(i==j)
    					sum=num[j][p-j+1];
    				else
    					sum=num[i][p-i+1]+num[j][p-j+1];
    				dp[p][i][j]+=sum;
    			}
    		}
    	}
    	printf("%d
    ", dp[n+m-1][m][m]);
    	return 0;
    }
    

      

     

    人十我百 人百我万
  • 相关阅读:
    RavenScheme简介
    我终于理解了LISP『代码即数据|数据即代码』的含义
    汉编随想(一)
    SICP的一些练习题
    linux下Script小计
    vscode小计
    软硬连接区别
    find过滤大小执行操作
    pyqt5和qt designer安装
    pyenv和virtualenv结合使用管理多python环境
  • 原文地址:https://www.cnblogs.com/bestcoder-Yurnero/p/10719065.html
Copyright © 2020-2023  润新知