給定乙個長度為n的數列ai,求ai的子串行bi的最長長度,滿足bi&bi-1!=0(2<=i<=len)。
輸入格式:
輸入檔案共2行。
第一行包括乙個整數n。
第二行包括n個整數,第i個整數表示ai。
輸出格式:
輸出檔案共一行。
包括乙個整數,表示子串行bi的最長長度。
輸入樣例#1:
31 2 3
輸出樣例#1:
2
對於100%的資料,1<=n<=100000,ai<=10^9。
solution:
本題只能說資料很水。
首先很容易套上最長上公升子串行的板子,我們設$f[i]$表示以第$i$個數結尾的最長序列長度,則$n^2$列舉轉移。
很顯然會超時,記得以前做$hnoi$的某道打鼴鼠題目時,介紹過乙個玄學優化可行性剪枝(學自巨佬——hzwer),定義個$mx[i]$表示前$i$個數中的最長序列長度,若當前的$f[i]>mx[i-1]$,則直接跳出迴圈,因為顯然最多也只能從前$i-1$個數中的最大長度$mx[i-1]+1$轉移過來,而現在$f[i]$至少不比這個值小,所以也就沒必要轉移了,那麼每次求出$f[i]$後,記住要更新$mx[i]=max(mx[i-1],f[i])$(被這卡了好一會兒!`~`),最後答案就是$mx[n]$啦。
**:
#include#define il inline#define for(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
#define max(a,b) ((a)>(b)?(a):(b))
using
namespace
std;
const
int n=200005
;int
n,a[n],f[n],mx[n];
il int
gi()
intmain()
cout
}
P4310 絕世好題
題目描述 給定乙個長度為n的數列ai,求ai的子串行bi的最長長度,滿足bi bi 1 0 2 i len 說明對於100 的資料,1 n 100000,ai 10 9。錯誤日誌 沒搞清 每一位的dp值如何更新記錄陣列 乙個數 a 可以接在數 b 後面,當他們在二進位制下有相同位同為 1 時成立 這...
P4310 絕世好題 題解
第一次看這道題首先想到的就是時間複雜度為 n 的求最長上公升子串行 for int i 1 i n i 這樣寫會超時 所以我們考慮更優秀的演算法,突破口就是位運算 題目中的操作是按位與,所以我們可以把乙個數的每乙個二進位制位分別拆分進行計算 我們設 f i 為當前二進位制位為 i 時滿足要求的最長長...
P4310 絕世好題 DP 題解
題面傳送門 p4310 絕世好題 第一眼以為是套路n2 dp,一看資料範圍1e5,直接懵逼5min 其實挺簡單的,題目也不錯 仔細想想挺簡單的,因為b i b i 1 0,那至少有一位二進位制位b i 和b i 1 均為1。然後我們考慮列舉bi的每一位二進位制1,在所有這一位也為1的數中,取以該數結...