洛谷 P1004 方格取数(DP)

题目链接:https://www.luogu.com.cn/problem/P1004

 

考虑让两个人同时走,设计状态则直接设f[i][j][k][m],表示第一个人走到(i,j),第二个人走到(k,m)时所取数的最大值。

当(i,j)==(k,m)时,即两个人走到同一个点,则这个点其实在第二遍的时候已经为0,所以这个点的贡献只是一次。

则有转移方程:

f[i][j][k][m]=max(f[i-1][j][k-1][m],max(f[i-1][j][k][m-1],max(f[i][j-1][k-1][m],f[i][j-1][k][m-1])));
if(i==k&&j==m) f[i][j][k][m]+=g[i][j];
else f[i][j][k][m]+=g[i][j]+g[k][m];

并且最后一维m不需要枚举,用i+j-k计算出来即可。(应该只能这样做)

 

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 const int N=10;
 6 int n,res;
 7 int a,b,c;
 8 int g[N][N],s[N],f[N][N][N][N];
 9 int main(){
10     scanf("%d",&n);
11     while(scanf("%d%d%d",&a,&b,&c)&&a!=0) g[a][b]=c;
12     for(int i=1;i<=n;i++)
13     for(int j=1;j<=n;j++)
14     for(int k=1;k<=n;k++){
15         int m=i+j-k;
16         if(m<0) continue;
17         f[i][j][k][m]=max(f[i-1][j][k-1][m],max(f[i-1][j][k][m-1],max(f[i][j-1][k-1][m],f[i][j-1][k][m-1])));
18         if(i==k&&j==m) f[i][j][k][m]+=g[i][j];
19         else f[i][j][k][m]+=g[i][j]+g[k][m];
20     }
21     printf("%d",f[n][n][n][n]);
22     return 0;
23 }
AC代码

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章