2014省赛大总结(三) 双线DP

来源:互联网 发布:软件开发热门发展方向 编辑:程序博客网 时间:2024/05/17 07:44
/*    http://acm.nyist.net/JudgeOnline/problem.php?pid=61  传纸条    http://acm.nyist.net/JudgeOnline/problem.php?pid=712 探 寻 宝 藏    题意:给一个矩阵,求两条不相交的线从左上角到右下角经过的元素的最大和    双线dp - 即同时考虑两条不相交的线,使其线上的和最大    显然我们需要记录每一步时两个线同时往前走的位置(这样可以容易的控制其不相交).    状态:dp[k,(x1,y1),(x2,y2)] 在第k步,双线里一线在(x1,y1) 二线在(x2,y2) 的最大和    转移:dp[k,(x1,y1),(x2,y2)] = max(dp[k-1,(x1-1,y1),(x2-1,y2)],                                      dp[k-1,(x1,y1-1),(x2-1,y2)],                                      dp[k-1,(x1-1,y1),(x2,y2-1)],                                      dp[k-1,(x1,y1-1),(x2,y2-1)]) + map[x1][y1] + map[x2][y2];*/ #include<iostream>#include<cstring>using namespace std;#define N   55int map[N][N],dp[2*N][N][N];int judge(int s, int i, int j,int n){    if(i == j)        return 0;    if (s-i < 1 || s-i > n || s- j< 1 || s-j > n)        return 0;    return 1;}int main(){    int k;    cin>>k;    while(k--)    {        memset(dp, 0, sizeof(dp));        int m,n;        cin>>m>>n;        for(int i = 1; i <= m; i++)            for(int j = 1; j <= n; j++)                cin>>map[i][j];        dp[2][1][1] = map[1][1];        for(int s = 3;  s < m + n; s++)            for(int i = 1; i <= m; i++)                for(int j = 1; j <= m; j++)                {                    if(judge(s,i,j,n))                    {                        int max1 = max(dp[s-1][i-1][j], dp[s-1][i-1][j-1]);                        int max2 = max(dp[s-1][i][j-1], dp[s-1][i][j]);                        dp[s][i][j] = max(max1, max2) + map[i][s-i] + map[j][s-j];                    }                }                int ret = max(dp[m+n-1][m-1][m], dp[m+n-1][m][m-1])+map[m][n];                cout<<ret<<endl;    }    return 0;}        


                                             
0 0
原创粉丝点击