首页 > 其他 > 详细

方格取数(DP)(NOIP2000)

时间:2015-09-17 23:01:17      阅读:322      评论:0      收藏:0      [点我收藏+]

不要多想,我不是无聊到刷NOIP2000的题目,只是老师用考试告诉我们,我们的DP很弱,so咱家来找道DP提做

还有,这个题貌似和矩阵取数那个没有什么关系

题目简述:给你一个N*N的方格(小的很,N只有10),你可以向右或向下走一步,并取走其中的数字,你要取两次,输出最后取数的和

首先,这是一个棋盘DP,我们从左上到右下DP就好了,我一开始打的是记录位置的方法,跑两次DP,然而坑了,那我们要在仔细分析一下问题,N很小,小到你能开到6维不会爆内存,所以大胆的去提高维度吧,在分析问题,其实我们要找的两条路径是最终取得的和最大

那我们可以开四维的DP数组DP[i][j][k][l],表示第一个点是(i,j)第二个点是(k,l)转移方程是DP[i][j][k][l] = max(all上一层可达的点)+ Map[i][j] + Map[k][l];

若两点重和则减去一个Map值;

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>

using namespace std;

typedef long long ll;

int Map[20][20];
int DP[20][20][20][20];

int main(){
    int n;
    scanf("%d",&n);
    int x,y,v;
    for (scanf("%d%d%d",&x,&y,&v);x != 0;scanf("%d%d%d",&x,&y,&v))
        Map[x][y] = v;
    for (int i = 1;i <= n; ++i)
        for (int j = 1;j <= n; ++j)
            for (int k = 1;k <= n; ++k)
                for (int l = 1;l <= n; ++l){
                    DP[i][j][k][l] = max(max(DP[i - 1][j][k - 1][l],DP[i - 1][j][k][l - 1]),max(DP[i][j - 1][k][l - 1],DP[i][j - 1][k - 1][l])) + Map[i][j] + Map[k][l];
                    if (i == k && j == l) 
                DP[i][j][k][l] -= Map[i][j];
                }
    printf("%d\n",DP[n][n][n][n]);
    return 0;
} 

 

方格取数(DP)(NOIP2000)

原文:http://www.cnblogs.com/GENEVE/p/4817720.html

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