P1004 [NOIP2000 提高组] 方格取数

文章讲述了两种方法处理矩阵中的状态转移问题,一种是四维动态规划,通过枚举四个坐标进行状态转移;另一种是一维到三维的优化,通过减少存储空间并计算总步数来简化。
摘要由CSDN通过智能技术生成

做法一:

四维dp

分别枚举两个位置的坐标,状态转移只能从两个位置的上面和左边转移。


using namespace std;

#define int long long 
#define endl '\n'

int a[10][10];
int f[10][10][10][10];
void solve()
{
    int n;
	cin>>n;
	
	int x,y,b;
	while(cin>>x,cin>>y,cin>>b && x!=0 && y!=0 && b!=0){
		a[x][y]=b;
	}
	
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			for (int k=1;k<=n;k++){
				for (int z=1;z<=n;z++){
					f[i][j][k][z]=max({f[i-1][j][k-1][z],f[i][j-1][k][z-1],f[i-1][j][k][z-1],f[i][j-1][k-1][z]})+a[i][j];
					
					if(i!=k && j!=z){
						f[i][j][k][z]+=a[k][z];
					}
					
				}
			}
		}
	}
	
	cout<<f[n][n][n][n];
	
	

}//思维做法。


signed main()
{
	
	int t;
	t=1;
	while(t--){
		solve();
	}
	
	
}

三维做法:
 

用一个总步数优化了一维,每个位置只需要保存一个坐标即可,因为总步数相同,所以可以知道这个点的具体坐标。

#include "bits/stdc++.h"
using namespace std;

#define int long long 
#define endl '\n'

int a[10][10];
int f[20][10][10];
void solve()
{
    int n;
	cin>>n;
	
	int x,y,b;
	while(cin>>x,cin>>y,cin>>b && x!=0 && y!=0 && b!=0){
		a[x][y]=b;
	}
	
	
	for (int i=1;i<=2*n;i++){
		for (int j=1;j<=i &&j<=n;j++){
			for (int k=1;k<=i && k<=n;k++){
				
			
				f[i][j][k]=max({f[i-1][j][k],f[i-1][j-1][k],f[i-1][j][k-1],f[i-1][j-1][k-1]})+a[j][i-j]+a[k][i-k];
				
				if(j==k){
					f[i][j][k]-=a[j][i-j];
				}
				
			}
		}
	}
	
	cout<<f[2*n][n][n];
	

}//思维做法。


signed main()
{
	
	int t;
	t=1;
	while(t--){
		solve();
	}
	
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值