洛谷P1004题解&心得
审题
源题目
题目见https://www.luogu.com.cn/problem/P1004
分析
这题就是一个动态规划的题目。
因为输入只给出几个有数值的点,所以我们要创建一个一位列表a,存储有数值的空间。(如果你指针可以的话那就用指针)(可以开10,但是最好开11,因为奇数比偶数快)
状态转移方程为:
n[x][y][j][k]=max{n[x+1][y][j+1][k],n[x][y+1][j+1][k],n[x+1][y][j][k+1],n[x][y+1][j][k+1]}+a[x][y]+a[k][l]。
说明:
比较历史记录{n[x+1][y][j+1][k] --都向右走
n[x][y+1][j][k+1] --都向下走
n[x+1][y][j][k+1] --第一次向右,第二次向下
n[x][y+1][j+1][k] --第一次向下,第二次向右}谁大,再加上a[x][y]、a[j][k]。
如果x==j、y==k那么就把多加的a[j][k]
删掉。
实现
创建输入
#include<iostream>
#include<algorithm>
using namespace std;
int n[11][11][11][11],a[11][11],n,x,y,z;
int main(){
cin>>n>>x>>y>>z;
while(!(x&&y&&z)){
a[x][y] = z;
cin>>x>>y>>z;
}
//TODO:算法
return 0;
}
创建算法
#include<iostream>
#include<algorithm>
using namespace std;
int n[11][11][11][11],a[11][11],n,x,y,z;
int main(){
cin>>n>>x>>y>>z;
while(!(x&&y&&z)){
a[x][y] = z;
cin>>x>>y>>z;
}
for(register int i(1);i<=n;++i){
for(register int j(1);j<=n;++j){
for(register int k(1);k<=n;++k){
for(register int l(1);l<=n;++l){
n[i][j][k][l]=max(max(n[i+1][j][k+1][l],n[i][j+1][k][l+1]),max(n[i+1][j][k][l+1],n[i][j+1][k+1][l])) + i==k&&j==l? a[i][j]:a[i][j]+a[k][l];
}
}
}
}
//TODO:创建输出
return 0;
}
创建输出
#include<iostream>
#include<algorithm>
using namespace std;
int n[11][11][11][11],a[11][11],n,x,y,z;
int main(){
cin>>n>>x>>y>>z;
while(!(x&&y&&z)){
a[x][y] = z;
cin>>x>>y>>z;
}
for(register int i(1);i<=n;++i){
for(register int j(1);j<=n;++j){
for(register int k(1);k<=n;++k){
for(register int l(1);l<=n;++l){
n[i][j][k][l]=max(max(n[i+1][j][k+1][l],n[i][j+1][k][l+1]),max(n[i+1][j][k][l+1],n[i][j+1][k+1][l])) + i==k&&j==l? a[i][j]:a[i][j]+a[k][l];
}
}
}
}
cout<<f[n][n][n][n];
return 0;
}
The end

浙公网安备 33010602011771号