标签:
不要多想,我不是无聊到刷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; }
标签:
原文地址:http://www.cnblogs.com/GENEVE/p/4817720.html