SX는 [2020년 1월 9일]는 NOIP 시뮬레이션 레이스 (DAY1)의 설정을 개선

[2020년 1월 9일]는 NOIP 시뮬레이션 레이스 (DAY1)의 설정을 개선

시험 결과는 할 수없는 시간이 지나면 두 가지 질문, 제목 부족의 속도로 수행, 첫 번째 두 가지 질문에 만족하지 않습니다.

 source : 100 + 20 + 0 + 0 = 120 rank7 

매우 비우호적.

글쎄, 그건 입력

\ (T1 \)

포털 : [USACO17JAN] 암소 소 댄스 댄스 쇼

분석

신선한 물 문제, 그것은 절반의 답을 생각하기 쉽고, 모노톤을 증명하기 쉽습니다.
그런 다음 허용을 고려 \ (\ 확인)
때 첫 번째 스택 유지되는 시간에 따라, 작은 힙 루트를 분석.
그런 다음 - 잘라
약간의 코드를

\ (T2 \)

포털 : [USACO17JAN]가 발굽 ,, 종이, 가위 발굽 가위 ...
현재가 더 어려울 수 없어야 합니다 (DP \) \ 있지만에 직접적인 타격을 전송하는 누설 검사 감소 방법을 고려 \ (20 \) 분.
문제의 의미에 따라 쉬운 상태 설정 생각 \ (F_는 {난, J, K가} \) 제 나타낸다 \ (I \) 의 변화가, 라운드 \ (j \) , 배 기회와 현재이다 \ (K \) ( H / S / P가 설정된다 \ (1/2/3 \) )
이체 :
설정 \ (P \) \ (Q는 \) 와 달리 나타낸다 (\ K \) 다른 두 개의 제스처, \ (승리 [I]가 [j]가 \)은 제스처 나타내는 \ (I \) 승 제스처 \ (J를 \) \ (a는 [I]는 \) 현재 나타냄 ) \ (\ FJ 가 제스처 :
\ [F [I] [J]를 [K]는 최대 = (F [I-1] [J-1] [P], F [I-1] [J-1] [Q], F [I-1] [J] [케이 ]) + 승 [K] 이 [I] \]

코드

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

const int N = 1e5;
int n , k , a[N + 5] , f[N + 5][25][4] , ans = 0 , p , q;
char ch;

int data[4][4];

int main()
{
//  freopen("hps.in" , "r" , stdin);
//  freopen("hps.out" , "w" , stdout);
    scanf("%d%d" , &n , &k);
    for(register int i = 1; i <= n; i++)
    {
        ch = getchar();
        while (ch != 'H' && ch != 'P' && ch != 'S') ch = getchar();
        if (ch == 'H') a[i] = 1;
        else if (ch == 'P') a[i] = 2;
        else if (ch == 'S') a[i] = 3;
    }
    data[1][3] = data[2][1] = data[3][2] = 1;
    for(register int i = 1; i <= n; i++) 
        for(register int j = 1; j <= 3; j++)
            f[i][0][j] = f[i - 1][0][j] + data[j][a[i]];
    for(register int i = 1; i <= n; i++)
        for(register int j = 1; j <= k; j++)
            for(register int l = 1; l <= 3; l++)
            {
                if (l == 1) p = 2 , q = 3;
                else if (l == 2) p = 1 , q = 3;
                else if (l == 3) p = 1 , q = 2;
                f[i][j][l] = max(f[i - 1][j][l] + data[l][a[i]], max(f[i - 1][j - 1][p] + data[l][a[i]] , f[i - 1][j - 1][q] + data[l][a[i]]));
            }
    for(register int i = 0; i <= k; i++)
        for(register int j = 1; j <= 3; j++)
            ans = max(f[n][i][j] , ans);
    printf("%d" , ans);
}

사라 ??????

\ (T3 \)

포털 : [USACO17JAN] 암소 탐색 소 탐색
코드입니다 어렵지만 내용과 더 많은 질문 많은 양의하지
(태그 \) \ :와 \ (BFS \) 시뮬레이션 할 \ (DP \)
는 다음과 같이 구체적으로 분석을 :
첫 번째 변환 : 때문에 우리가 시작점으로 설정하므로,지도 이유 판독 \ ((N, 1) \ ) , 엔드 포인트 (\ (1, N) \
) 은 각각 두 개의 소가 \ ((N, 1) \ ) 2 개 종 방향 대향를
그리고 참고 : 상관없이 다른 가축, 그는 움직이지 않는 것, 새로운 명령을 무시하지 않는 소를 종료합니다, 현재 명령이 소가 선이 움직이지 않은 교차했을 경우. (피사체에 더 심각한 얼굴 용)

집합 \ (F_는 {X1은, Y1, D1, X2, Y2, D2는} \) 소 도착 나타내는 \ ((X1, Y1) \ ) 대향 \ (D1 \) , 소 두 도착 \ ((X2, Y2)를 \ ) 에 대한 \ (D2 \) 명령어 최소 길이
의한 각각의 명령의 기여도에 대답 \ (1 \) , 그것을 사용하는 것이 가능하다 ) \ \합니다 (BFS 가장 짧은 측부 연장 업데이트 할 ) \ (\ DIS
하지만 실제로 기절 공간을 최적화 할 수 있습니다 \ (D2 \) 그 차원
이 개 소는 동일한 명령을 수신하기 때문에, 자신의 방향에 따라 다른 측면을 알 수있을 것입니다 어느 알고, 상대적으로 좋은의 생각을 으로 시작

코드

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

const int N = 20;

int n , map[N + 5][N + 5] , head , tail , ans = 1e5;
int f[N + 5][N + 5][4][N + 5][N + 5][4] , vis[N + 5][N + 5][4][N + 5][N + 5][4];
int fx[4][2] = { -1 , 0 , 0 , 1 , 1 , 0 , 0 , -1 };
char ch;

struct node{
    int x1 , y1 , d1 , x2 , y2 , d2;
}q[N * N * N * N * 16 + 10];

inline bool check(int x , int y , int xx , int yy)
{
    return (x <= 0 || y <= 0 || x > n || y > n || map[x][y] == 1 || (xx == 1 && yy == n));
}

int main()
{
//  freopen("cow.in" , "r" , stdin);
//  freopen("cow.out" , "w" , stdout);
    
    scanf("%d" , &n);
    for(register int i = 1; i <= n; i++)
        for(register int j = 1; j <= n; j++)
        {
            while (ch != 'E' && ch != 'H') ch = getchar();
            if (ch == 'H') map[i][j] = 1;
            ch = getchar();
        }
    q[++tail] = (node){n , 1 , 0 , n , 1 , 1};
    memset(f , 0x3f , sizeof(f));
    f[n][1][0][n][1][1] = 0;
    vis[n][1][0][n][1][1] = 1;
    while (head < tail)
    {
        struct node now = q[++head];
        int x1 , y1 , d1 , x2 , y2 , d2;
        
        d1 = now.d1 , d2 = now.d2;
        x1 = now.x1 + fx[d1][0] , y1 = now.y1 + fx[d1][1];
        if (check(x1 , y1 , now.x1 , now.y1)) x1 = now.x1 , y1 = now.y1;
        x2 = now.x2 + fx[d2][0] , y2 = now.y2 + fx[d2][1];
        if (check(x2 , y2 , now.x2 , now.y2)) x2 = now.x2 , y2 = now.y2;
        if (f[now.x1][now.y1][now.d1][now.x2][now.y2][now.d2] + 1 < f[x1][y1][d1][x2][y2][d2] && vis[x1][y1][d1][x2][y2][d2] == 0)
        {
            q[++tail] = (node){x1 , y1 , d1 , x2 , y2 , d2};
            f[x1][y1][d1][x2][y2][d2] = f[now.x1][now.y1][now.d1][now.x2][now.y2][now.d2] + 1;
            vis[x1][y1][d1][x2][y2][d2] = 1;
        }
        
        d1 = (now.d1 + 1) % 4 , d2 = (now.d2 + 1) % 4;
        x1 = now.x1 , y1 = now.y1 , x2 = now.x2 , y2 = now.y2;
        if (f[now.x1][now.y1][now.d1][now.x2][now.y2][now.d2] + 1 < f[x1][y1][d1][x2][y2][d2] && vis[x1][y1][d1][x2][y2][d2] == 0)
        {
            q[++tail] = (node){x1 , y1 , d1 , x2 , y2 , d2};
            f[x1][y1][d1][x2][y2][d2] = f[now.x1][now.y1][now.d1][now.x2][now.y2][now.d2] + 1;
            vis[x1][y1][d1][x2][y2][d2] = 1;
        }
        
        d1 = (now.d1 + 3) % 4 , d2 = (now.d2 + 3) % 4;
        x1 = now.x1 , y1 = now.y1 , x2 = now.x2 , y2 = now.y2;
        if (f[now.x1][now.y1][now.d1][now.x2][now.y2][now.d2] + 1 < f[x1][y1][d1][x2][y2][d2] && vis[x1][y1][d1][x2][y2][d2] == 0)
        {
            q[++tail] = (node){x1 , y1 , d1 , x2 , y2 , d2};
            f[x1][y1][d1][x2][y2][d2] = f[now.x1][now.y1][now.d1][now.x2][now.y2][now.d2] + 1;
            vis[x1][y1][d1][x2][y2][d2] = 1;
        }
    }
    for(register int i = 0; i < 4; i++) 
        for(register int j = 0; j < 4; j++)
            ans = min(ans , f[1][n][i][1][n][j]);
    printf("%d" , ans);
}

\ (T4 \)

포털 : 서브 시퀀스 반전 역순는 [USACO17JAN]
해석이 아니라 다음 :
이 제목을 시작하는 것은 불가능 것입니다 실제로는 매우 일상적인 간격 \ (민주당이 \)
만을 값에 따라 (1 ~ 50 \) \ 특성, 우리는 마법의 작업을 사용할 수 있습니다 노크 소위 플립
ADO, 룩
세트 \ (F_을 {I, J, 상하} \) 의 간격을 나타내는 \ ([I, J] \) 의 수치 범위 (\ [DOWN, UP] \) 긴 시퀀스의 길이는
다음 간격 합니다 (DP \) \ 루틴 전송하지만, 두 부분이 서로 중첩되어 전이

코드

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

const int N = 50;
int n , f[N + 5][N + 5][N + 5][N + 5] , a[N + 5] , Mx;

int main()
{
//  freopen("reversal.in" , "r" , stdin);
//  freopen("reversal.out" , "w" , stdout);
    scanf("%d" , &n);
    for(register int i = 1; i <= n; i++)
    {
        scanf("%d" , &a[i]);
        for(register int down = 1; down <= a[i]; down++)
            for(register int up = a[i]; up <= 50; up++)
                f[i][i][down][up] = 1;
    }
    for(register int len1 = 2; len1 <= n; len1++)
        for(register int i = 1; i <= n - len1 + 1; i++)
        {
            register int j = i + len1 - 1;
            for(register int len2 = 2; len2 <= 50; len2++)
                for(register int down = 1; down <= 51 - len2; down++)
                {
                    register int up = down + len2 - 1 , Mx;
                    Mx = max(f[i][j][down + 1][up] , f[i][j][down][up - 1]);
                    Mx = max(f[i + 1][j][down][up] + (a[i] == down) , Mx);
                    Mx = max(f[i][j - 1][down][up] + (a[j] == up) , Mx);
                    Mx = max(f[i + 1][j - 1][down][up] + (a[j] == down) + (a[i] == up) , Mx);
                    f[i][j][down][up] = Mx;
                }
        }
    printf("%d" , f[1][n][1][50]);
}

추천

출처www.cnblogs.com/leiyuanze/p/12173650.html