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;
    }        


  • 相关阅读:
    ZOJ 1002 Fire Net (火力网)
    UVa OJ 117 The Postal Worker Rings Once (让邮差只走一圈)
    UVa OJ 118 Mutant Flatworld Explorers (变体扁平世界探索器)
    UVa OJ 103 Stacking Boxes (嵌套盒子)
    UVa OJ 110 MetaLoopless Sorts (无循环元排序)
    第一次遇到使用NSNull的场景
    NSURL使用浅析
    从CNTV下载《小小智慧树》
    NSDictionary and NSMutableDictionary
    Category in static library
  • 原文地址:https://www.cnblogs.com/james1207/p/3270952.html
Copyright © 2011-2022 走看看