2019牛客暑期多校訓練1

2022-05-03 13:06:32 字數 2981 閱讀 5134

equivalent prefixes

這個是乙個用單調棧的題目,至於為什麼可以用單調棧?

把兩個陣列同時跑單調棧,如果每次進棧最多乙個,當然在這個進棧之前肯定會有數出棧,

如果存在乙個數進棧了,然後這個時候判斷一下進棧的這個數的位置是不是相同,如果不相同就說明肯定是不對的。

為什麼說這個時候只要考慮這個棧內的位置呢?

首先,這個最小值之前的數肯定是不要考慮的,因為當前的棧底就是目前位置最小的了,之後的數和之前的數rmq函式返回的函式值肯定是這個棧底。

然後就是考慮棧內元素,這個應該很好想了。

#include //

描述中的「如果找到,就說「x,let』s fly」(此處,x為開始時間)…"

#include //

和output中的 「x, let's fly」

#include //

裡的「 』 」和 「 ' 」 不是乙個符號,別複製錯了!!!

#include #include

#include

#include

#include

#include

#include

#define inf 0x3f3f3f3f

#define inf64 0x3f3f3f3f3f3f3f3f

using

namespace

std;

const

int maxn = 1e5 + 10

;typedef

long

long

ll;int

queue_mina[maxn];

intqueue_minb[maxn];

inta[maxn], b[maxn];

intmain()

r++;

}printf(

"%d\n

", ans);

}return0;

}

aabba

這個題目是乙個dp,現在看完題解之後感覺還比較好想,但是這個條件的判斷我覺得還是比較難的。

就是判斷哪一種一定不是答案

下面有兩種寫法,理解了任意一種另一種都可以很快的寫出來

if(i-j>n||j-i>m)//

為什麼這麼寫就是對的呢?

//因為i代表的是a的數量,j代表的是b的數量,如果a-b的數量大於n,就說明前面至少有n+1個a,這個b的數肯定

//有一部分在後面,所以這樣的話ab的數量肯定》n,這樣就不對了,後面的j-i>m 同理可得。

//這裡可以篩出一部分肯定不對的,那麼為什麼滿足這個就肯定是正確的呢。

//這個可以這麼理解,這個if條件句把一定不對的篩出去了,如果後面有不合理的狀態放到了dp陣列裡面

//最後一直往後走放a,b前面不合理的狀態還是會被篩出去的

這個是一種dp轉移 dp[x][y]表示選了x個a,y個b的方案數

#include #include 

#include

#include

#include

#include

#include

#include

#define inf 0x3f3f3f3f

#define inf64 0x3f3f3f3f3f3f3f3f

using

namespace

std;

const

int maxn = 1e5 + 10

;typedef

long

long

ll;const

int mod = 1e9 + 7

;ll dp[

4400][4400

];int

main()

}for(int i=0;i<=(n+m);i++)

if (i == 0 || j == 0) dp[i][j] = 1

;

else dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) %mod;}}

printf(

"%lld\n

", dp[n + m][n +m]);

}return0;

}

1這個是dp[x][y]表示前面x個位置選了y個b的方案數

#include #include 

#include

#include

#include

#include

#include

#include

#define inf 0x3f3f3f3f

#define inf64 0x3f3f3f3f3f3f3f3f

using

namespace

std;

const

int maxn = 1e5 + 10

;typedef

long

long

ll;const

int mod = 1e9 + 7

;ll dp[

4400][4400];

intmain()

}dp[

0][0] = 1

;

if (n != 0) dp[1][1] = 1

;

if (m != 0) dp[1][0] = 1

;

for(int i=1;i<=2*(n+m);i++)

if (j == 0) dp[i][j] = 1

;

else dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1]) %mod;}}

printf(

"%lld\n

", dp[2 * (n + m)][n + m]%mod);

}return0;

}

2

2019牛客多校訓練(五)

求出類似斐波那契數列的第 n 項 n leq 10 我想著尤拉降冪。其實尤拉降冪並不適用於矩陣的運算 隊友看了題之後立馬想到十進位制的矩陣快速冪,太強了 和普通的矩陣不同的是,這個每次乘十前進,但這不是問題 對矩陣快速冪的時間複雜度認識得不深,潛意識以為 n 是乙個無窮大的數 include def...

2019牛客多校訓練(四)

給出一顆樹 讓所有染色點到某個點的最大距離最小 結果為最遠點對的距離除二向上取整 假設有最遠點對的路徑上的中間點 如果有某個點它到這個中間點要遠,那麼最遠點對就不是最遠點對了,產生矛盾 利用樹上點對路徑唯一性,兩次 dfs 求出染色點直徑 include define ll long long de...

2019牛客暑期多校訓練營(第九場)

d knapsack cryptosystem 折半搜尋,晚上又去看了挑戰程式設計,對於時間複雜度高的情況,可以通過犧牲空間來降低時間複雜度。先把前半部分所有可以組合的情況列舉出來,然後對於後半部分依次列舉,那麼複雜度變化為o 2 36 o 2 18 2 18log 18 顯然就可做了,折半的裸題。...