zoukankan      html  css  js  c++  java
  • nyist 61 传纸条 nyist 712 探 寻 宝 藏(双线程dp问题)

    http://acm.nyist.net/JudgeOnline/problem.php?pid=61

    http://acm.nyist.net/JudgeOnline/problem.php?pid=712

    这是双进程DP问题,首先,假设出发点为A 终点为B 那么,根据题目给出的条件,可以推出A->B的动态转移方程为 dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + a[i][j]; 由于,同理可得B的情况,那么,题目的意思是A->B 然后 B -> A我们可以假设同时从A点出发,得到两条不同路径,这个是一样的效果。所以,我们可以得到一个动态转移方程

    dp[i][j][p][q] = max(dp[i-1][j][p-1][q],dp[i-1][j][p][q],dp[i][j-1][p-1][q],dp[i][j-1][p][q-1]) 因为 每次只能移动一步,即 i+1 或j+1 那么 i+j是移动的步数 因为从A点开始移动的,经过相同的步数,肯定能得到i+j = p+q
    还有一点要注意一下,这题与NYOJ 61是同类问题,但是,有一点细节要注意,最后终点的值也要算上,上面的动态方程得到的值不包含两个A 和 B的值,因为 A是起点,所以,他的值一般是0,所以,得到最后的结果应该是 int sum = max(dp[m-1][n][m-1][n],dp[m-1][n][m][n-1],dp[m][n-1][m-1][n],dp[m][n-1][m][n-1]) + a[m][n];

    nyist 61代码

    #include <iostream>
    #include <cstring>
    using namespace std;
    int a[55][55],dp[55][55][55][55];
    int main(int argc, char *argv[])
    {
    	int t,n,m,i,j,p,q,ans;
    	cin>>t;
    	while(t--)
    	{
    		cin>>n>>m;
    		for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)
    		cin>>a[i][j];
    		memset(dp,0,sizeof(dp));
    		for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)
    		for(p=i+1;p<=n;p++)
    		{
    			q=i+j-p;
    			if(q<=0) continue;
    			dp[i][j][p][q] = max(max(dp[i-1][j][p-1][q],dp[i][j-1][p][q-1]),
                                             max(dp[i-1][j][p][q-1],dp[i][j-1][p-1][q])) + a[i][j] + a[p][q];
    		}
    		ans=max(max(dp[n-1][m][n-1][m],dp[n-1][m][n][m-1]),
                          max(dp[n][m-1][n-1][m],dp[n][m-1][n][m-1]));
      		cout<<ans<<endl;
    	}
    	return 0;
    }


    nyist 712代码:

     
    #include <iostream>
    #include <cstring>
    using namespace std;
    int a[55][55],dp[55][55][55][55];
    int main(int argc, char *argv[])
    {
    	int t,n,m,i,j,p,q,ans;
    	cin>>t;
    	while(t--)
    	{
    		cin>>n>>m;
    		for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)
    		cin>>a[i][j];
    		memset(dp,0,sizeof(dp));
    		for(i=1;i<=n;i++)
    		for(j=1;j<=m;j++)
    		for(p=i+1;p<=n;p++)
    		{
    			q=i+j-p;
    			if(q<=0) continue;
    			dp[i][j][p][q] = max(max(dp[i-1][j][p-1][q],dp[i][j-1][p][q-1]),
                                             max(dp[i-1][j][p][q-1],dp[i][j-1][p-1][q])) + a[i][j] + a[p][q];
    		}
    		ans=max(max(dp[n-1][m][n-1][m],dp[n-1][m][n][m-1]),
                          max(dp[n][m-1][n-1][m],dp[n][m-1][n][m-1]));
      		cout<<ans+a[n][m]<<endl;
    	}
    	return 0;
    }        


  • 相关阅读:
    第二次冲刺阶段第四天
    第二次冲刺阶段第三天
    第二次冲刺阶段第二天
    人月神话阅读笔记03
    第二次冲刺阶段第一天
    学习进度条(十二)
    课堂练习-找水王
    学习进度条(十一)
    学习进度表第十周
    构建之法阅读笔记06
  • 原文地址:https://www.cnblogs.com/james1207/p/3270952.html
Copyright © 2011-2022 走看看