首页 > 其他 > 详细

[NOIP2008] 传纸条 题解

时间:2019-10-05 18:48:20      阅读:80      评论:0      收藏:0      [点我收藏+]

题目描述:

技术分享图片

 

题解:

首先转换一下问题,原问题就等价于从找两条从$(1,1)$到$(n,m)$的互不相交的路径,使得路径上数值的和最大。

首先考虑令$f[i,j,k,l]$表示两条路径到$(i,j)$于$(k,l)$时的最大夹着,这时候我们发现,如果知道了“走”了多少步,那么只要知道横坐标(或纵坐标),就能根据走的步数算出令一个坐标,一举两等,大大简化状态转移。

于是我们令$f[k,i,j]$表示当走了k步,第一张纸条到第i行,第二张纸条到第j行时的最大价值。

于是状态转移方程为:

  $f[k,i,j]=max{f[k-1][i][j](两个都向右走),f[k-1][i][j-1],f[k-1][i-1][j](一个向右一个向下),f[i-1][i-1][j-1](都向下走)}$

 注意循环对i,j的时候,j从i+1开始(为了保证路径不重合,也可以做到不重不漏)。

附上代码:

#include<bits/stdc++.h>
using namespace std;

int a[60][60],f[101][60][60];
int n,m;


int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
            scanf("%d",&a[i][j]);
    for(int k=2;k<=n+m-1;++k){
        for(int i=1;i<=n;++i){
            for(int j=i+1;j<=n;++j){
                if(!(k-i+1) || !(k-j+1) ||(k-i+1>m+1) || (k-j+1)>m+1) continue;//有效位置
                f[k][i][j]=max(f[k-1][i-1][j-1],f[k-1][i][j]);
                f[k][i][j]=max(f[k][i][j],max(f[k-1][i][j-1],f[k-1][i-1][j]))+a[i][k-i+1]+a[j][k-j+1];
            }
        }
    }
    printf("%d",f[n+m-1][n-1][n]);
    return 0;
}

 

[NOIP2008] 传纸条 题解

原文:https://www.cnblogs.com/Asika3912333/p/11625171.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!