[NOIp2000提高组]方格取数

[NOIp2000提高组_T4]方格取数

这道题主要考验的是对DP的理(nao)解(dong)

四维DP很好理解

dp[i][j][k][p]表示第一条路径走到i,j、第二条路径走到k,p时的最大值

所以就要知道i,j、k,p上一步的最大值

分别是:i-1,k-1(向上)

        j-1,p-1(向左)

        i-1,p-1(第一条路径向上,第二条路径向左)

        j-1,k-1(第一条路径向左,第二条路径向上)

要求最大值可得方程:

buf=max(dp[i-1][j][k-1][p],dp[i][j-1][k][p-1]);
buf=max(buf,max(dp[i-1][j][k][p-1],dp[i][j-1][k-1][p]));
dp[i][j][k][p]=buf+f[i][j];

 

 1 #include<iostream>
 2 #include<stdio.h>
 3 using namespace std;
 4 int n,x,y,z,buf,f[20][20],dp[20][20][20][20];
 5 int main()
 6 {
 7     scanf("%d",&n);
 8     while(~scanf("%d%d%d",&x,&y,&z))
 9         f[x][y]=z;
10     for(int i=1;i<=n;++i)
11     {
12         for(int j=1;j<=n;++j)
13         {
14             for(int k=1;k<=n;++k)
15             {
16                 for(int p=1;p<=n;++p)
17                 {
18                     //选取上一步的最优路径 
19                     buf=max(dp[i-1][j][k-1][p],dp[i][j-1][k][p-1]);
20                     buf=max(buf,max(dp[i-1][j][k][p-1],dp[i][j-1][k-1][p]));
21                     //加上这个点的数值 
22                     dp[i][j][k][p]=buf+f[i][j];
23                     //如果这个点没有被重复走,那么再加一次 
24                     if(i!=k && j!=p)
25                         dp[i][j][k][p]+=f[k][p];
26                 }
27             }
28         }
29     }
30     printf("%d",dp[n][n][n][n]);
31 }
原文地址:https://www.cnblogs.com/__Kgds/p/9511544.html