[usaco gold 2016.1]无线电通信

本文介绍了一个路径规划问题,目标是最小化两移动个体间的累计电量消耗。通过动态规划方法求解,预处理移动路径坐标,实现高效计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

农夫约翰和奶牛贝西要去寻找丢失的奶牛,为了彼此能联系对方,他们带着无线电通讯设备。不幸的是电池快没有电了。所以它们要尽量节省电能。农夫从位置(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[i][j]: Farmer John走第i步,奶牛贝茜走到第j步时,最少消耗的电量
dp[i][j]=min( dp[i-1][j-1], dp[i][j-1], dp[i-1][j] )+cost( i, j )

把每一步的坐标都预处理出来,算cost的时候方便一些


#include<iostream> 
#include<cstring> 
#include<cstdio> 
#include<cstdlib> 
#include<cmath> 
#include<algorithm> 
using namespace std; 
const int INF=0x7f7f7f7f; 
const int N=1010; 
struct node{ int x, y; }f[N], b[N]; 
int n, m, dp[N][N]; 
char way[N]; 
  
int Cost( node a, node b ) {  
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);  
} 
  
int main() { 
    scanf( "%d%d", &n, &m ); 
    scanf( "%d%d", &f[0].x, &f[0].y ); 
    scanf( "%d%d", &b[0].x, &b[0].y ); 
    scanf( "%s", way+1 ); 
    for( int i=1; i<=n; i++ ) { 
        if( way[i]=='E' ) f[i].x=f[i-1].x+1, f[i].y=f[i-1].y; 
        else if( way[i]=='S' ) f[i].x=f[i-1].x, f[i].y=f[i-1].y-1; 
        else if( way[i]=='W' ) f[i].x=f[i-1].x-1, f[i].y=f[i-1].y; 
        else if( way[i]=='N' ) f[i].x=f[i-1].x, f[i].y=f[i-1].y+1; 
    } 
    scanf( "%s", way+1 ); 
    for( int i=1; i<=m; i++ ) { 
        if( way[i]=='E' ) b[i].x=b[i-1].x+1, b[i].y=b[i-1].y; 
        else if( way[i]=='S' ) b[i].x=b[i-1].x, b[i].y=b[i-1].y-1; 
        else if( way[i]=='W' ) b[i].x=b[i-1].x-1, b[i].y=b[i-1].y; 
        else if( way[i]=='N' ) b[i].x=b[i-1].x, b[i].y=b[i-1].y+1; 
    } 
      
    memset( dp, 0x7f, sizeof dp ); dp[0][0]=0; 
      
    for( int i=0; i<=n; i++ ) 
        for( int j=0; j<=m; j++ ) { 
            int w=INF; 
            if( i ) w=min( w, dp[i-1][j] ); 
            if( j ) w=min( w, dp[i][j-1] ); 
            if( i && j ) w=min( w, dp[i-1][j-1] ); 
            dp[i][j]=min( dp[i][j], w+Cost( f[i], b[j] ) ); 
        } 
      
    printf( "%d\n", dp[n][m] ); 
    return 0; 
} 


### USACO 2016 Copper Problems and Information USACO(United States of America Computing Olympiad)是一个面向全球编程爱好者的竞赛平台,尤其受到高中生欢迎。对于2016年的铜级别比赛,以下是几个具有代表性的题目及其描述: #### Promotion Counting 【USACO 2016 January Contest, Bronze】 在这个问题中,给定一组奶牛的位置以及它们晋升的情况,需要统计特定条件下能够被提升的奶牛数量[^1]。 ```cpp // 这里提供的是一个简化版的例子用于说明逻辑结构而非具体实现细节 #include <iostream> using namespace std; int main(){ int n; cin >> n; // 处理输入并计算结果... } ``` #### Cities and States 【USACO 2016 December Contest, Silver but mentioned in bronze context】 此题涉及城市名称和州名之间的匹配关系。给出多个城市的名称与其所在的州缩写,要求找出满足一定条件的城市对的数量[^2]。 ```cpp // 同样仅展示框架性代码片段 string city_names[], state_codes[]; for (each pair){ check_condition_and_count(); } cout << count_result; ``` #### Angry Cows 【USACO 2016 January Contest, Bronze】 这是一个关于覆盖区间的问题。假设有一系列位于直线上的目标点(草堆),通过调整发射物(奶牛)的影响范围来尽可能高效地摧毁所有目标。任务是要找到最小的有效影响半径使得全部目标都能受到影响[^3]。 ```cpp vector<int> positions; // 存储各个草堆的位置 double findMinRadius(int k){ /* ... */ } ``` #### Circular Barn 【USACO 2016 February Contest, Bronze】 该问题是围绕着优化路径展开的。在一个环形布局下安排访问顺序,目的是使总的行走距离最短。解决方案涉及到遍历不同的起始位置,并评估由此产生的总成本,最终选取最优解[^4]。 ```cpp LL solveOptimalPath(vector<int>& distances){ LL bestCost = numeric_limits<LL>::max(); for(size_t start=0 ;start<distances.size();++start){ calculate_cost_from_start(start); update_best_if_better(bestCost,currentCost); } return bestCost; } ``` 这些例子展示了不同类型的算法挑战,从简单的计数到更复杂的贪心策略或是动态规划方法的应用。每个问题都旨在测试参赛者的基础编程技能以及解决问题的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值