P1004 [NOIP2000 提高组] 方格取数

 将先后两次路线当作一次走两条路,路线可以重复,但价值只能计数一次

 k = i1 + j1 = i2 + j2

以下分别对每一步作了详细的注释


#include <iostream>
#include <algorithm>

using namespace std;
const int N = 10 + 9;

int n,m;
int g[N][N];
int f[2* N][N][N];

void solve()
{
	int x,y,w;
	cin >> n;
	
	while(cin >> x >> y >> w,x || y || w)	g[x][y] = w;
	
	for (int k = 2;k <= 2 * n;k ++) //k代表横纵坐标之和;初值为2:A点坐标为(1,1),截止为2 * n:B点坐标为(n,n)
		for (int i1 = 1;i1 <= n;i1 ++)
			for (int i2 = 1;i2 <= n;i2 ++)
			{
				int j1 = k - i1,j2 = k - i2;
				//t => 价值
				int t = g[i1][j1];
				if (i1 != i2) t += g[i2][j2]; //两次走相同的方块,价值只算一次
				
				int &x = f[k][i1][i2];
				
				//上一步的情况
				x = max(x,f[k - 1][i1 - 1][i2 - 1] + t);//都从上过来
				x = max(x,f[k - 1][i1 - 1][i2] + t);//从上,从左过来
				x = max(x,f[k - 1][i1][i2 - 1] + t);//从左,从上过来
				x = max(x,f[k - 1][i1][i2] + t);//都从左过来
			}
	cout << f[2 * n][n][n] << endl;
}

int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int _ = 1;
	while(_--) solve();
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值