nyoj 61 传纸条(一)

来源:互联网 发布:免流端口 编辑:程序博客网 时间:2024/05/09 12:02


题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=61


分析: 一道双线程动态规划题,与第六届河南acm比赛的题类似.

题意:小纸条从(1,1)传到(m,n),再传回来,并且路线不能交叉,使好感度之和最高.我们可以认为是同时找出两条从(1,1)传到(m,n)的不相交的路线.

方法是:

计算每一步情况下的情况,一条道路用i,j控制,另一条用x,y控制.


从矩阵的角度看,k对应的是一条一条的斜线,值为横纵坐标之和,从3(1+2)开始,到m+n-2.i从1到m-1,对应的j为k-i,x从2到m,对应的y为k-j;


dp[k%2][i][x]中记录的是从(1,1)到(i,j),(x,y)两个点的最大好感度。a由计算得到,随横坐标变化。


状态转移为从需要计算的两点的(上,上),(上,左),(左,上),(左,左)方向的两点到(i,j),(x,y)的最大好感度+map[i][j]+map[x][y]。

代码为:

for(k=3;k<m+n;k++)        {            for(i=1,j=k-i;i<m;i++,j--)            {                if(j>n||j<=1)                    continue;                for(x=i+1,y=k-x;x<=m;x++,y--)                {                    if(y>=n||y<1)                        continue;                    dp[k%2][i][x]=map[i][j]+map[x][y];                    tmp=(k-1)%2;                    dp[k%2][i][x]+=max(max(dp[tmp][i-1][x-1],dp[tmp][i-1][x]),max(dp[tmp][i][x-1],dp[tmp][i][x]));                }            }        }

我的程序效率不是太高,看别人的博客说用网络流能更优化算法,可惜我不会网络流,要学的东西还很多。加油!!!

附上我的程序

#include <iostream>#include <algorithm>#include <cstring>#define MAXN 61using namespace std;int main(){    int T,m,n,i,j,k,x,y,tmp;    int map[MAXN][MAXN],dp[2][MAXN][MAXN];    cin>>T;    while(T--)    {        cin>>m>>n;        memset(dp,0,sizeof(dp));        for(i=1;i<=m;i++)            for(j=1;j<=n;j++)                cin>>map[i][j];        for(k=3;k<m+n;k++)        {            for(i=1,j=k-i;i<m;i++,j--)            {                if(j>n||j<=1)                    continue;                for(x=i+1,y=k-x;x<=m;x++,y--)                {                    if(y>=n||y<1)                        continue;                    dp[k%2][i][x]=map[i][j]+map[x][y];                    tmp=(k-1)%2;                    dp[k%2][i][x]+=max(max(dp[tmp][i-1][x-1],dp[tmp][i-1][x]),max(dp[tmp][i][x-1],dp[tmp][i][x]));                }            }        }        cout<<dp[(m+n-1)%2][m-1][m]<<endl;    }    return 0;}


0 0