洛谷P2905 [USACO08OPEN]农场危机Crisis on the Farm

P2905 [USACO08OPEN]农场危机Crisis on the Farm

题目描述

约翰和他的奶牛组建了一只乐队“后街奶牛”,现在他们正在牧场里排练.奶牛们分成一堆 一堆,共1000)堆.每一堆里,30只奶牛一只踩在另一只的背上,叠成一座牛塔.牧场 里还有M(1 < M < 1000)个高高的草垛.

作为出色的指挥家,约翰可以通过口哨指挥奶牛们移动.他的口哨有四个音,分别能使所有 的牛塔向东南西北四个方向移动一格.

每一次,当一个牛塔到达了一个草垛所在的格子,牛塔最上方的奶牛就会跳到草垛上,而且 不再下来,而其他奶牛仍然呈塔状站在草垛所在的格子里.当牛塔只剩一只奶牛时,这只奶牛也 会跳到草垛上.

突然,约翰大惊失色:原来邻家的奶缸爆炸了!滚滚而下的牛奶正朝着约翰的牧场冲来,不久就要将牧场淹没.约翰必须马上行动,用口哨声挽救奶牛们的生命.他要指挥奶牛尽量多地跳 上草操,草操上的奶牛将不会被淹死.

约翰还有K次吹口哨的机会.那他最多还能救多少奶牛呢?请计算最多能挽救的奶牛数,以及 达到这个数目约翰需要吹的口哨调子序列.序列用E,W,S,N表示东西南北.如果有多种序列能达到 要求,输出作为字符串最小的.

输入输出格式

输入格式:

  • Line 1: Three space-separated integers: N, M, and K
  • Lines 2..N+1: Line i+1 describes the X,Y location of a stack of 30 cows using two space-separated integers: X_i and Y_i
  • Lines N+2..N+M+1: Line i+N+1 describes the X,Y location of a haystack using two space-separated integers: X_i and Y_i

输出格式:

  • Line 1: A single integer that is the most number of cows that can be saved.
  • Line 2: K characters, the lexicographically least sequence of commands FJ should issue to maximize the number of cows saved.

输入输出样例

输入样例#1:

3 6 3
3 4
6 2
5 7
8 2
9 2
6 4
5 4
6 7
8 7

输出样例#1:

6
EEE

说明

Use the ‘east‘ whistle three times, at which point the milk floods the area. Each haystack ends up saving 1 cow.

对于100%的数据,1\le K\le 30,1\le N,M,X_i,Y_i\le 10001≤K≤30,1≤N,M,X?i??,Y?i??≤1000

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 1500
using namespace std;
int n,m,K,ans;
int dx[4]={1,0,0,-1};
int dy[4]={0,1,-1,0};
char step[40][64][64];
char C[4]={‘W‘,‘S‘,‘N‘,‘E‘};
int cnt[64][64],f[40][64][64]; //f[k][i][j]记录走k步,纵向移动了i-31步,横向移动了j-31步,所能拯救的最多的牛的数量。
int cawx[MAXN],cawy[MAXN],grassx[MAXN],grassy[MAXN];//记录牛和草垛的横纵坐标.
int main(){
    scanf("%d%d%d",&n,&m,&K);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&cawx[i],&cawy[i]);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&grassx[i],&grassy[i]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            int cx=cawx[i]-grassx[j];    //第i头牛移动到第j个草垛,纵向最少所走的距离.
            int cy=cawy[i]-grassy[j];    //第i头牛移动到第j个草垛,横向最少所走的距离.
            if(abs(cx)<=30&&abs(cy)<=30)//因为k<=30,所以当有一个方向的距离大于30,就不用考虑了,因为一定不可能走到.
                cnt[cx+31][cy+31]++;    //否则cnt记录走纵向i步横向走j步所能拯救的牛的数量.
        }
    for(int k=0;k<=K;k++)
        for(int i=0;i<=62;i++)
            for(int j=0;j<=62;j++){
                f[k][i][j]=-0x3f3f3f3f;
                step[k][i][j]=‘Z‘;
            }
    f[0][31][31]=cnt[31][31];    //赋初值,最开始时所能拯救的牛的数量为0.
    //这里要理解,因为他可以向上下左右走,为了防止负坐标的出现,我们把一开始时的原点坐标当做(31,31).
    for(int k=1;k<=K;k++)
        for(int i=1;i<=61;i++)
            for(int j=1;j<=61;j++)
                f[k][i][j]=cnt[i][j]+max(max(f[k-1][i-1][j],f[k-1][i+1][j]),max(f[k-1][i][j-1],f[k-1][i][j+1]));
                //这个状态转移方程就不用解释了,还是很容易理解的.
    for(int i=1;i<=61;i++)
        for(int j=1;j<=61;j++)
            ans=max(ans,f[K][i][j]);
    for(int i=1;i<=61;i++)
        for(int j=1;j<=61;j++)
            if(ans==f[K][i][j])
                step[K][i][j]=‘A‘;    //如果为纵向走i步横向走j步是一种可行的走法,记录以方便求字典序最小.
    for(int k=K-1;k>=0;k--)
        for(int i=1;i<=61;i++)
            for(int j=1;j<=61;j++)
                for(int l=0;l<4;l++)
                    if(f[k][i][j]+cnt[i+dx[l]][j+dy[l]]==f[k+1][i+dx[l]][j+dy[l]]&&step[k+1][i+dx[l]][j+dy[l]]<‘Z‘)
                        step[k][i][j]=C[l];    //倒序找出所有可能的走法.
    cout<<ans<<endl;
    int i=31,j=31;
    for(int k=0;k<K;k++){
        cout<<step[k][i][j];
        if(step[k][i][j]==‘E‘)    i--;    //找字典序最小的.
        else if(step[k][i][j]==‘W‘)    i++;
        else if(step[k][i][j]==‘S‘)    j++;
        else if(step[k][i][j]==‘N‘)    j--;
    }
}
时间: 2024-08-23 13:28:15

洛谷P2905 [USACO08OPEN]农场危机Crisis on the Farm的相关文章

洛谷 P2905 [USACO08OPEN]农场危机Crisis on the Farm(恶心的DP)

P2905 [USACO08OPEN]农场危机Crisis on the Farm 1605: [Usaco2008 Open]Crisis on the Farm 牧场危机 题目描述 约翰和他的奶牛组建了一只乐队“后街奶牛”,现在他们正在牧场里排练.奶牛们分成一堆 一堆,共1000)堆.每一堆里,30只奶牛一只踩在另一只的背上,叠成一座牛塔.牧场 里还有M(1 < M < 1000)个高高的草垛. 作为出色的指挥家,约翰可以通过口哨指挥奶牛们移动.他的口哨有四个音,分别能使所有 的牛塔向东南

洛谷 P2905 [USACO08OPEN]农场危机Crisis on the Farm

题目描述 约翰和他的奶牛组建了一只乐队“后街奶牛”,现在他们正在牧场里排练.奶牛们分成一堆 一堆,共1000)堆.每一堆里,30只奶牛一只踩在另一只的背上,叠成一座牛塔.牧场 里还有M(1 < M < 1000)个高高的草垛. 作为出色的指挥家,约翰可以通过口哨指挥奶牛们移动.他的口哨有四个音,分别能使所有 的牛塔向东南西北四个方向移动一格. 每一次,当一个牛塔到达了一个草垛所在的格子,牛塔最上方的奶牛就会跳到草垛上,而且 不再下来,而其他奶牛仍然呈塔状站在草垛所在的格子里.当牛塔只剩一只奶牛

P2905 [USACO08OPEN]农场危机Crisis on the Farm

传送门 DP 设 f [ i ] [ j ] [ k ] 表示已经走了 i 步,向上走了 j 步,向右走了 k 步时能拯救的最多奶牛数(j,k可以为负,表示反向) 设 g [ i ] [ j ] 表示牛向上走 i 步,向右走 j 步后有多少奶牛恰好在草堆上(同样 i , j 可负) 那么 f [ i ] [ j ] [ k ] = max( f [ i-1 ] [ j -1 ] [ k ] , f [ i-1 ] [ j ] [ k-1 ] , f [ i-1 ] [ j+1 ] [ k ] ,

洛谷 P2908 [USACO08OPEN]文字的力量Word Power

P2908 [USACO08OPEN]文字的力量Word Power 题目描述 Farmer John wants to evaluate the quality of the names of his N (1 <= N <= 1000) cows. Each name is a string with no more than 1000 characters, all of which are non-blank. He has created a set of M (1 <= M

洛谷 P2909 [USACO08OPEN]牛的车Cow Cars

P2909 [USACO08OPEN]牛的车Cow Cars 题目描述 N (1 <= N <= 50,000) cows conveniently numbered 1..N are driving in separate cars along a highway in Cowtopia. Cow i can drive in any of M different high lanes (1 <= M <= N) and can travel at a maximum speed

洛谷 P3079 [USACO13MAR]农场的画Farm Painting

P3079 [USACO13MAR]农场的画Farm Painting 题目描述 After several harsh winters, Farmer John has decided it is time to re-paint his farm. The farm consists of N fenced enclosures (1 <= N <= 50,000), each of which can be described by a rectangle in the 2D plane

洛谷P2906 [USACO08OPEN]牛的街区Cow Neighborhoods

曼哈顿距离转切比雪夫距离 1 #include <bits/stdc++.h> 2 #define LL long long 3 #define GG int 4 #define For(i, j, k) for(register int i=j; i<=k; i++) 5 #define Dow(i, j, k) for(register int i=j; i>=k; i--) 6 using namespace std; 7 GG read() { 8 GG x = 0, f

洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N x N 的方格.输入数据中包括有树的方格的列表.你的任务是计算并输出,在他的农场中,不需要砍树却能够修建的最大正方形牛棚.牛棚的边必须和水平轴或者垂直轴平行. EXAMPLE 考虑下面的方格,它表示农夫约翰的农场,‘.'表示没有树的方格,‘#'表示有树的方格 1 2 3 4 5 6 7 8 1 .

洛谷P1589 泥泞路

洛谷P1589 泥泞路 题目描述 暴雨过后,FJ的农场到镇上的公路上有一些泥泞路,他有若干块长度为L的木板可以铺在这些泥泞路上,问他至少需要多少块木板,才能把所有的泥泞路覆盖住. 输入输出格式 输入格式: 第一行为正整数n(≤10000)和L(≤10000),分别表示有多少段泥泞路和木板的长度:接下来n行,每一行两个整数s和e(s≤e≤10^9),表示每一段泥泞路的起点和终点. 输出格式: 仅一个正整数,表示木板数. 输入输出样例 输入样例#1: 复制 3 3 1 6 13 17 8 12 输出