給定乙個序列,判斷其是否可能為乙個二叉樹的中序遍歷序列,該二叉樹樹邊連線的兩個點的值不能互質。
第一行乙個數字t,表示測試組數
對於每一組測試樣例
第一行乙個數字n,表示序列長度
第二行有n個數字ai,表示這個序列
t≤5,n≤500,2≤ai≤10^9
輸出t行,"yes"或"no"
2
65 4 7 9 5 4
42 6 3 4
no
yes
n才500,預處理出 ok[i][j] 表示a[i]與a[j]之間可以連樹邊。接下來考慮區間 dp,l[l][r]表示區間[l,r] 是否可以作為 r 的左兒子,r[l][r]表示區間[l,r]是否可以作為 l 的右兒子。
那麼 l[l][r]=true 的前提是存在乙個k(l≤k≤r-1)滿足: l[l][k]&&r[k][r-1]&&ok[k][r]
同理 r[l][r]=true 的前提是存在乙個k(l+1≤k≤r)滿足:l[l+1][k]&&r[k][r]&&ok[l][k]
分析之後發現區間dp複雜度為n^3,n為500,樣例好像比較水,1s時間能過。
#include#define inf 0x3f3f3f3f3f3f3f3f
#define lowbit(a) ((a)&(-(a)))
#define ll long long
using namespace std;
int n,m,a[505];
bool l[505][505],r[505][505],ok[505][505];
inline void init()
}}int main()
}for(int len=1;len<=n;len++)
for(int i=1;i<=n-len;i++) //r[i][i+len]
for(int j=i+1;j<=i+len;j++)
if(l[i+1][j]&&r[j][i+len]&&ok[i][j])
}bool flag=false;
for(int i=1;i<=n;i++)
if(l[1][i]&&r[i][n])
if(flag)
puts("yes");
else
puts("no");
}return 0;
}
2018第一場多校 補題
distinct values ps 思路巨明顯,就是 寫不出,總想著一次更新一條線段。這裡用乙個set,存的是當前能用的數的。怎麼去更新set,記錄上乙個區間的左右端點 l r 然後類似於莫隊的寫法。看 吧。注意上乙個區間和當前區間沒有公共端點時要特判!也就是 中的 if 語句 include i...
暑假訓練第一場C
題目 小的時候大家一定玩過 井 字棋吧。也就是在九宮格中,只要任意行 列,或者任意連續對角線上面出現三個相同的,就能獲勝。現在小明和小花也在玩三子棋,但是他們不是在九宮格裡,而是在3 4的格仔裡面。現在小明先下,但是他知道小花這個人很聰明,他想知道第一步下在哪乙個地方最合適,你能幫幫他嗎?input...
2018 計蒜之道 初賽 第一場
題解 典型的二分 1 pragma warning disable 4996 2 include3 include4 include 5 include6 include7 include8 include9 define ll long long 10using namespace std 111...