給定正整數序列x1,….. , xn 。
(1)計算其最長遞增子串行的長度s。
(2)計算從給定的序列中最多可取出多少個長度為s的遞增子串行。
(3)如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長
度為s的遞增子串行。
第1 行有1個正整數n,表示給定序列的長度。接
下來的1 行有n個正整數x1…..xn 。
第1 行是最長遞增子串行的長度s。第2行是可取出的長度為s 的遞增子串行個數。第3行是允許在取出的序列中多次使用x1和xn時可取出的長度為s 的遞增子串行個數。
4
3 6 2 5
2
23
第一問dp,然後我就不會做了…
聯絡到最大流每個流代表乙個方案,可以這樣建圖:
數列每個點拆點,然後連流量為1的邊,表示只能選一遍。
對於第一問得到的dp陣列,表示以第
i 位結尾的最長遞增子串的長度。若dp
[i]=
1,則s向i連邊,容量為1;若dp
[i]=
maxl
en(也就是第一問答案),則i′
向e連邊,容量為1。
然後若i
>j且
a[i]
>=a[
j]且d
p[i]
==dp[
j]+1
,則i′ 向
j 連邊,容量為1。
然後跑最大流,每個流表示乙個方案。
對於第三問,把與第1個和第n個點相關的邊改為inf即可(也就是
<1,
1′>n′
>1>,e
>
),跑一遍最大流即可。
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int inf = 1000000010;
const
int sz = 1000010;
int head[sz],nxt[sz],tot = 1,n;
struct edgel[sz];
void build(int f,int t,int d)
void insert(int f,int t,int d)
int deep[sz];
queue
q;bool bfs(int s,int e)}}
return
false;
}int dfs(int u,int flow,int e)
else deep[v] = 0;}}
return flow - rest;
}int dinic(int s,int e)
int dp[sz],num[sz],len = 0;
void init()
int ask(int p)
if(dp[i] == len)
}for(int i = 1;i <= n;i ++)
for(int j = i + 1;j <= n;j ++)
if(num[i] <= num[j] && dp[i] + 1 == dp[j])
insert(i + n,j,1);
return dinic(s,e);
}int main()
printf("%d\n",len);
printf("%d\n",ask(1));
printf("%d\n",ask(inf));
return
0;}
codevs1906 最長遞增子串行問題
題目描述 description 給定正整數序列x1,xn 1 計算其最長遞增子串行的長度s。2 計算從給定的序列中最多可取出多少個長度為s的遞增子串行。3 如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長 度為s的遞增子串行。輸入描述 input description ...
最長遞增子串行
這是微軟實習生筆試遇到的,題意 求乙個陣列中最長遞增子串行的長度。要求選擇該題最好演算法的時間複雜度和空間複雜度。答案 時間複雜度o nlgn 空間複雜度o n 這題明顯用動態規劃來解。假設在目標陣列array 的前i個元素中,以array i 元素為最大元素的遞增子串行的長度是lis i 那麼 遞...
最長遞增子串行
最長遞增子串行又叫做最長上公升子串行 子串行,正如lcs一樣,元素不一定要求連續。本節討論實現三種常見方法,主要是練手。題 求乙個一維陣列arr i 中的最長遞增子串行的長度,如在序列1,1,2,3,4,5,6,7中,最長遞增子串行長度為4,可以是1,2,4,6,也可以是 1,2,4,6。方法一 d...