洛谷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

posted @ 2022-01-20 21:37  StarStream  阅读(165)  评论(0)    收藏  举报