SX [2020年1月9日] NOIPシミュレートレース(1日目)のセットを改善

【2020年1月9日] NOIPシミュレートレースのセット(1日目)を改善

試験結果は、タイトル不足ペースとして行う、実行する時間がない後の最初の2つの質問、二つの質問に満足のいくものではありません。

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

非常に非友好的。

まあ、それが入力されています

\(T1 \)

ポータル:[USACO17JAN]牛の牛のダンス・ダンスショー

分析

新鮮な水の問題は、それが半分答えを考えることは容易である、モノトーンを証明するのは簡単です。
そして、許容考える\(\空)
ときに最初のスタックの保守にかかる時間に基づいて、小さなヒープルートを分析します。
そして、 -カット
少しのコードを

\(T2 \)

ポータル:[USACO17JAN]フーフ,,紙、シザー蹄はさみ...
現在はへのより困難あってはならない(DP \)\、しかし、への直接打撃転送の漏れ検査のA方式考慮\(20 \)分。
状態を設定することを考えるように簡単に、問題の意味によると、\(F_ {I、J、 Kは} \) 最初表し\(I \)のラウンドを、そこに変更です\(J \)回のチャンスがあり、現在は\(K \) H / S / Pに設定されている(1/2/3 \)\
転送:
設定\(P \)、\ (Q \)が異なり表す(K \)\他の二つのジェスチャの、\(勝利[I] [J] \)を表すジェスチャー\(I \)勝利ジェスチャー\(J \)、\ ([I] \)は、現在を表す\(FJ \)ジェスチャーがある:
\ [F [I] [J] [K] =最大 (F [I-1] [J-1] [P]、F [I-1] [J-1]〜[Q]、F [I-1]〜[J] [K ])+勝利[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)\
) はそれぞれ、2頭を持っている\()(nは、1 \ ) その二つの方向に面します
ノートに:すべての新しいコマンドを無視して牛を終了するには、どのような他の牛に関係なく、彼は移動しませんが、現在の命令は、牛がラインが動かなかった交差しているだろう持っている場合。(主題でより深刻な表情の場合)

セット\(F_ {X1、Y1、 D1、X2、Y2、D2} \) ウシ到着表す\((X1、Y1)を\ ) に面する\(D1 \)を、ウシ2到着\((X2、Y2)\ )のための\(D2 \)命令最小長
による各命令の寄与に答えである\(1 \) それは使用することが可能である)\ \(BFS最も短側縁延長更新を行う)\(\ DIS
実際にはノックのスペースを最適化することができます\(D2 \)その寸法
に応じて、他の側面を知ることができるようになりますどの1知るために、素敵な思想は、2頭の牛が同じ命令を受けたので、その方向は相対的です向けてスタート

コード

#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]は
次の通りに解釈:
タイトルを起動することは不可能だが、実際には非常に日常的な間隔です\(DP \)
のみ値に応じて(1〜50 \)\特性、我々は魔法の動作を使用することができますフリップいわゆるノック
ADO、ルック
セット\(F_ {I、J、上下} \) 間隔を表す\([I、J] \)数値範囲、\([上下] \)最も長いシーケンス長は
、次にインターバル(DP \)\ルーチン転送が、2つのセクションでは、ネストされた一緒に転移しています

コード

#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