長度為n
nn的序列,分割成兩個上公升子串行要求長度差最小
我們對於i
ai≥a ji iai≥ aj的點之間連邊,然後可以對於乙個聯通塊進行二分圖染色,我們可以發現,如果我們先固定乙個點的顏色,那麼這個聯通塊的二分圖染色方案數為1或0。 之後兩個聯通塊互不影響,所以我們可以用dpdp dp來計算方案。 考慮繼續優化,我們可以發現如果i ii到j jj之間有連邊,那麼對於任意乙個i < k i< kii和k kk和j jj必定聯通,那麼我們可以推得乙個聯通塊必定是乙個區間,而乙個區間的分界點滿足該點前面的所有數都比後面的所有數要小。 因為劃分方案數為2cn t2^ 2cnt (cnt為聯通塊數量。所以聯通塊數量不超過log (1e18 )log(1e18) log(1e 18),可以通過本題 #include #include #include using namespace std; const int n= 1e5+ 10,k= 300; int t,n,a[n] ,maxs[n] ,mins[n] ;int cnt,b[k] ,e[k] ,z[k] ;bool f[2] [n]; stack< int> q1,q2; intmain() mins[n+1] =2147483647/3 ;cnt=0; for( int i=n;i>= 1;i-- ) mins[i] =min (mins[i+1] ,a[i]); for( int i= 1;i<=n;i++)if (maxs[i] <=mins[i+1] ||i==n) b[++cnt] =e[cnt-1] +1,e[cnt] =i;bool flag=0; for( int i= 1;i<=cnt;i++)} if(flag) break ; z[i] =q1. size() -q2. size() ;}if(flag) memset (f,0 ,sizeof (f)) ; f[0] [0]= 1;for( int i= 1;i<=cnt;i++ )for (int j= 0;j<=n;j++ ) f[i&1] [j]=f[ ~i&1][ abs(j-z[i])] |f[~i&1] [abs (j+z[i])] ;for (int j= 0;j<=n;j++)if (f[cnt&1] [j]) }} 給乙個長度為 n 的陣列 a 試將其劃分為兩個嚴格上公升子串行,並使其長度差最小。當 max 1,i 時顯然兩個區間互不影響,把 i 視為分界點 若相鄰的兩個分界點 i,j 所組成的區間 i sim j 如果合法只有一種劃分方法 所以把合法區間貢獻扔入揹包裡搞一搞就可以了 include inclu... 題目描述 乙個只包含非負整數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列,我們可以得到一些上公升的子串行,這裡1 i1 i2 ik n。例如 對於序列,有它的一些上公升子串行,如,等等。這些子串行中序列和最大的是子串行,它的所有元素的和為18。對於給定的乙個序列... time limit 1000ms memory limit 65536k 乙個只包含非負整數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列,我們可以得到一些上公升的子串行,這裡1 i1 i2 ik n。例如 對於序列,有它的一些上公升子串行,如,等等。這些子串行...#include
揹包 nssl 1488 上公升子串行
上公升子串行
上公升子串行