#bzoj3037#无线电通信(DP)

3037: 无线电通信

时间限制: 1 Sec  内存限制: 128 MB

题目描述

农夫约翰和奶牛贝西要去寻找丢失的奶牛,为了彼此能联系对方,他们带着无线电通讯设备。不幸的是电池快没有电了。所以它们要尽量节省电能。农夫从位置(fx,fy)出发,一共走N步,贝西从位置(bx,by)出发,一共走M步。农夫的路线是由一个长度为N的字符串限制,字符串只出现’N’或’E’或’S’或’W’中,表示东南西北四个方向。农夫每一单位时间可以选择不动,或者按照限制走出一步。奶牛贝西也是如此。但他们必须走完这个字符串。无线电设备每一单位时间消耗的电量等于他们的距离的平方。请问,他们走到终点,最少消耗多少电量?

输入

第一行两个整数n,m(1<=n,m<=1000),第二行为fx,fy表示农夫的起始位置,第三行为bx,by,表示贝西的起始位置。
接下来有两个字符串,第一个字符串表示农夫的路线,第二个字符串表示贝西的路线。
他们的坐标总是在(0<=x,y<=1000)。北是y的正方向,东为x的正方向。

输出

输出一个整数,表示最少消耗的电量。

样例输入

2 7
3 0
5 0
NN
NWWWWWN

样例输出

28
很简单的DP

Dp[i][j]表示约翰走到第i步,奶牛走到第j步的最小距离和

Dp[i][j] = min(Dp[i - 1][j], Dp[i][j - 1], Dp[i - 1][j - 1]) + dis(i, j)

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;

const int Max = 1000;

struct node{
	int x, y;
	node(){}
	node(int a, int b){x = a, y = b;}
}Pos[2][Max + 5];

int N, M;
int Farx, Fary, Cowx, Cowy;
int Dp[Max + 5][Max + 5];
char Path[2][Max + 5];

void getint(int & num){
	char c;	int flg = 1;	num = 0;
	while((c = getchar()) < '0' || c > '9')	if(c == '-')	flg = -1;
	while(c >= '0' && c <= '9'){	num = num * 10 + c - 48;	c = getchar();}
	num *= flg;
}

void Pre_pos(){
	int All[2] = {N, M};
	for(int flg = 0; flg < 2; ++ flg){
		for(int i = 1; i <= All[flg]; ++ i){
			Pos[flg][i] = Pos[flg][i - 1];
			if(Path[flg][i] == 'N')	++ Pos[flg][i].y;
			if(Path[flg][i] == 'S')	-- Pos[flg][i].y;
			if(Path[flg][i] == 'E')	++ Pos[flg][i].x;
			if(Path[flg][i] == 'W')	-- Pos[flg][i].x;
		}
	}
}	

double Get_Cost(int a, int b){
	return (Pos[0][a].x - Pos[1][b].x) * (Pos[0][a].x - Pos[1][b].x) + (Pos[0][a].y - Pos[1][b].y) * (Pos[0][a].y - Pos[1][b].y);
}

int main(){
	//freopen("radio.in", "r", stdin);
	//freopen("radio.out", "w", stdout);
	getint(N), getint(M);
	getint(Pos[0][0].x), getint(Pos[0][0].y);
	getint(Pos[1][0].x), getint(Pos[1][0].y);
	scanf("%s%s", Path[0] + 1, Path[1] + 1);
	Pre_pos();
	for(int i = 0; i <= N; ++ i)
		for(int j = 0; j <= M; ++ j)	Dp[i][j] = 0x3f3f3f3f;
	Dp[0][0] = 0;
	for(int i = 0; i <= N; ++ i)
		for(int j = 0; j <= M; ++ j)	if(i || j){
			int cost = Get_Cost(i, j);
			if(i)	Dp[i][j] = min(Dp[i][j], Dp[i - 1][j]);
			if(j)	Dp[i][j] = min(Dp[i][j], Dp[i][j - 1]);
			if(i && j)	Dp[i][j] = min(Dp[i][j], Dp[i - 1][j - 1]);
			Dp[i][j] += cost;
		}
	printf("%d\n", Dp[N][M]);
	return 0;
}	





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值