1. 程式人生 > >洛谷10月月賽R1·浴谷八連測R1·提高組 SAC E#1

洛谷10月月賽R1·浴谷八連測R1·提高組 SAC E#1

清晰版題目描述
小強拿到一個3×n的陣列,要在每一列選一個數(或者不選),滿足以下條件:
1.如果在第一行選,那它必須大於等於上一個數
2.如果在第二行選,那麼必須小於等於上一個數
3.如果在第三行選,對於連續的一段在第三行選的數,必須滿足方向相同(都小於等於上一個數或者都大於等於上一個數)

20分:暴力列舉每一個位置 不選,選1,選2,選3
60分:用dp[i][j]表示第 i 列選第 j 行達到的最長長度。
設 dp i,j 表示:第 i 個位置選擇第 j 個序列的數,前 i 個位置
所能構成的最長子序列的長度。特別的,dp i,2 表示第 i 個位
置選擇第三個序列的數,且大於等於前一個數;dp i,3 表示
第 i 個位置選擇第三個序列的數,且小於等於前一個數。
dp i,1 = max(dp j,k ),(1≤ j < i,1≤ k ≤ 4,a j,k ≤ a i,1 ) + 1
dp i,2 = max(dp j,k ),(1 ≤ j < i,1 ≤ k ≤ 4,a j,k ≥ a i,2 ) + 1
dp i,3 = max(dp j,k ),(1≤ j < i,1 ≤ k ≤ 4,k≠4,a j,k ≤ a i,3 ) + 1
dp i,4 = max(dp j,k ),(1≤ j < i,1≤ k ≤ 4,k≠3,a j,k ≥ a i,4) + 1
邊界條件:dp 0,j = 0。
狀態數 O(n),轉移複雜度 O(n),總複雜度 O(n^2 )。
100分:在60分的基礎上,在選取最大值的時候,用樹狀陣列來優化 (需要離散化)


在這裡要用8個樹狀陣列,為了節省程式碼量,我們只用樹狀陣列來計算前面的最大值 ( 所以需要加上一些特殊處理 ) 例如當需要a j,k>=a i,2時我們可以按照m-a i,2來查詢(a j,k>=a i,2 即 m-a j,k <= m-a i,2)。

60分裸的dp

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define M 100009
#define LL long long
using namespace std
; int n,a[M][5],dp[M][5],ans; int main() { scanf("%d",&n); for(int j=1;j<=3;j++)for(int i=1;i<=n;i++) scanf("%d",&a[i][j]); for(int i=1;i<=n;i++) a[i][4]=a[i][3]; for(int i=1;i<=n;i++) { for(int j=1;j<i;j++) { for(int k=1;k<=4
;k++) { if(a[j][k]<=a[i][1]) dp[i][1]=max(dp[i][1],dp[j][k]+1); if(a[j][k]>=a[i][2]) dp[i][2]=max(dp[i][2],dp[j][k]+1); if(a[j][k]>=a[i][3]&&k!=4) dp[i][3]=max(dp[i][3],dp[j][k]+1); if(a[j][k]<=a[i][4]&&k!=3) dp[i][4]=max(dp[i][4],dp[j][k]+1); } } } for(int i=1;i<=4;i++) ans=max(ans,dp[n][i]); printf("%d",ans); return 0; }

100分

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define M 100009
#define LL long long
using namespace std;
int n,a[M][5],dp[M][5],ans;
int te[10][M*3],t[M*3],tot,m;
inline int read()
{
    register int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
int query(int id,int x)
{
    int s=0;
    for(int i=x;i;i-=(-i)&i)
     s=max(te[id][i],s);
    return s;
}
void update(int id,int x,int p)
{
    for(int i=x;i<=m;i+=i&(-i))
     te[id][i]=max(te[id][i],p);
}
int main()
{
    scanf("%d",&n);
    for(int j=1;j<=3;j++)
     for(int i=1;i<=n;i++) 
      a[i][j]=read(),t[++tot]=a[i][j];

    sort(t+1,t+tot+1);
    m=unique(t+1,t+tot+1)-t-1;
    for(int j=1;j<=3;j++)
     for(int i=1;i<=n;i++)
      a[i][j]=lower_bound(t+1,t+m+1,a[i][j])-t;//離散化 

    for(int i=1;i<=n;i++)
    {
        dp[i][1]=max(dp[i][1],query(1,a[i][1])+1);
        dp[i][1]=max(dp[i][1],query(3,a[i][1])+1);
        dp[i][1]=max(dp[i][1],query(5,a[i][1])+1);
        dp[i][1]=max(dp[i][1],query(7,a[i][1])+1);

        dp[i][2]=max(dp[i][2],query(2,m-a[i][2]+1)+1);
        dp[i][2]=max(dp[i][2],query(4,m-a[i][2]+1)+1);
        dp[i][2]=max(dp[i][2],query(6,m-a[i][2]+1)+1);
        dp[i][2]=max(dp[i][2],query(8,m-a[i][2]+1)+1);

        dp[i][3]=max(dp[i][3],query(1,a[i][3])+1);
        dp[i][3]=max(dp[i][3],query(3,a[i][3])+1);
        dp[i][3]=max(dp[i][3],query(5,a[i][3])+1);

        dp[i][4]=max(dp[i][4],query(2,m-a[i][3]+1)+1);
        dp[i][4]=max(dp[i][4],query(4,m-a[i][3]+1)+1);
        dp[i][4]=max(dp[i][4],query(8,m-a[i][3]+1)+1);

        update(1,a[i][1],dp[i][1]);
        update(3,a[i][2],dp[i][2]);
        update(5,a[i][3],dp[i][3]);
        update(7,a[i][3],dp[i][4]);

        update(2,m-a[i][1]+1,dp[i][1]);
        update(4,m-a[i][2]+1,dp[i][2]);
        update(6,m-a[i][3]+1,dp[i][3]);
        update(8,m-a[i][3]+1,dp[i][4]);
    } 
    for(int i=1;i<=4;i++) ans=max(ans,dp[n][i]);
    printf("%d",ans);
    return 0;
}

相關推薦

10月月R1·八連R1·提高 SAC E#1

清晰版題目描述 小強拿到一個3×n的陣列,要在每一列選一個數(或者不選),滿足以下條件: 1.如果在第一行選,那它必須大於等於上一個數 2.如果在第二行選,那麼必須小於等於上一個數 3.如果在第三行選,對於連續的一段在第三行選的數,必須滿足方向相同(

10月月R1·八連R1·提高 T2

傳送門! 最簡單的暴力:輸出N(20)! 正解DP: 60DP: dp[i][j]為選第i行到第j位置最長的符合要求的序列長度。 我們把第三個序列選上升的定義為dp[3][j] 下降的定義為dp[4][j]。 狀態轉移: 很明顯 dp[1][

10月月R1·普及

ack com iostream read n) none 水題 cin 初始 SAC E#1 - 一道不可做題 Jelly 這題是大水題,隨便AC。 就是要註意一點:初始溫度與熔點的大小關系。 就是因為這個。。wa了。。 #include<iostream>

10月月II

#A: P4924 [1007]魔法少女小Scarlet 這道題考了矩陣旋轉 其實很考驗推公式的能力和程式碼能力 這裡有個小技巧 可以設(x, y)為原點,然後去推公式,然後實際操作中橫座標加上x,縱座標加上y就好了。 順時針(i, j) -> (j, -i) 逆時針(i, j) ->

10月月弐·黑科技第一題階梯報告

題目描述 uim最近在研究一種遊戲,叫做“yyy棋”。 這種遊戲的規則很簡單,就是有一個A*B的棋盤和黑白兩色的棋子,兩個人輪流在下在格子裡面。你可以下黑棋或者白棋,中途可以更換顏色,可以下在任何你喜歡的地方,但是要符合以下條件: 1、這個位置不能已經被別

10月月Round.1 A.絲綢之路

#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #inclu

 10月月II  P4932 瀏覽器

題目背景 __stdcall在用Edge玩slay的時候,滑鼠會經常失靈,這讓她十分痛苦,因此她決定也要讓你們感受一下Edge製造的痛苦。 題目描述 __stdcall給了你n個點,第i個點有權值x[i],對於兩個點u和v,如果x[u] xor x[v]的結果

月月

bfs scanf col sca 貪心 排序 ont pre open A題 分析:直接貪心即可,註意要long long 1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #in

9月月T1——預生成密碼

-a cnblogs turn code -o style su- col blog 其實這題只是一道比較簡單的數學題。 輸入給出了a,b,c三個數的與或和 由於要a盡可能小,a相同則b盡可能小,b相同則c盡可能小 所以a最小一定是and,此時若要b盡可能小,c就要盡可能大

【LGR-047】5月月

cti stat strong 半徑 要求 一起 lin 算法 pac 這次我期待了很久的Luogu賽制崩掉了 傳說中的Luogu神機就這樣被卡爆了 然後我過了20min才登上Luogu的網站,30min後才看到題目 然後交T1TM的不給我測!!!然後又叫了一次機子就炸了,

5月月】玩遊戲(NTT,生成函數)

wap class char gist 一個 我們 max 卷積 include 【洛谷5月月賽】玩遊戲(NTT,生成函數) 題面 Luogu 題解 看一下要求的是什麽東西 \((a_x+b_y)^i\)的期望。期望顯然是所有答案和的平均數。 所以求出所有的答案就在乘一個逆

5月月T30212 玩遊戲 【分治NTT + 多項式求ln】

LG AI getchar make DG mit pla con 形式 題目鏈接 洛谷T30212 題解 式子很容易推出來,二項式定理展開後對於\(k\)的答案即可化簡為如下: \[k!(\sum\limits_{i = 0}^{k} \frac{\sum\limits_

【題解】6月月 —— 「數學」約數個數和

分解 pri clas left pac 這樣的 DC 兩個 探測   看德國戰墨西哥去了結果發現比賽只剩下30分鐘……當然之後又思考這題挺久也還是不會做。看了一下題解,覺得這個做法挺厲害的,在這裏記錄一下:   原式實際上就是:(\(K +=

【LGR-049】7月月

while size printf class jump 二分 ++ 一個 sin Preface Luogu八月月賽都結束了我才來補七月月賽 這次月賽還是很狗的,在紹一的晚上恰逢刮臺風,然後直接打到一半斷網了 結果都沒有交上去GG 感覺這次難度適中,解法也比較清新自然吧,

月月T1】簽到題(bsgs)(快速乘)

code 是我 好的 取模 lin pri sca ast for 說好的簽到題呢qwq。。。。怎麽我簽到題都不會啊qwq 之後看了bsgs才發現貌似不是那麽那麽難fake!!什麽東西。。。 先貼上部分分做法(也就是枚舉1的個數,然後每一步都進行取模(這和最後取模結果一樣,

月月

如果 打表 奇數 new 回文 十月 http clas 維護 (比賽鏈接)[https://www.luogu.org/contestnew/show/11084] T1 50分 : 暴力 100分· : 臨時數組記錄位置 T2 先看s = 0時 對於一個合理串 把它每一

月月2T1瀏覽器P4932

傳送門 https://www.luogu.org/problemnew/show/P4932 題面 題目描述 __stdcall給了你n個點,第i個點有權值x[i],對於兩個點u和v,如果x[u] xor x[v]的結果在二進位制表示下有奇數個1,那麼在u和v之間連線一個Edg

「P4996」「11月月」 咕咕咕(數論

題目描述 小 F 是一個能鴿善鵡的同學,他經常把事情拖到最後一天才去做,導致他的某些日子總是非常匆忙。 比如,時間回溯到了 2018 年 11 月 3 日。小 F 望著自己的任務清單: 看 iG 奪冠; 補月賽題的鍋。 小 F 雖然經常咕咕咕,但他完成任務也是很厲害的,他一次性可以完成剩

[11月月]

比賽連結 T1 思路 按照斐波那契的式子到著往前推就行,f[i]=f[i+2] - f[i+1],當找到某個值使得f[i] = 0,f[i+1] = 1的時候就停止。 程式碼 //https://www.luogu.org/problemnew/show/P4994 #include<cstd

「P4994」「11月月」 終於結束的起點(枚舉

一次 分享 ted main orange 多少 質因子 生涯 nbsp 題目背景 終於結束的起點終於寫下句點終於我們告別終於我們又回到原點…… 一個個 OIer 的競賽生涯總是從一場 NOIp 開始,大多也在一場 NOIp 中結