码迷,mamicode.com
首页 > 其他好文 > 详细

方格取数(DP)(NOIP2000)

时间:2015-09-17 23:01:19      阅读:267      评论: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
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!