«問題描述:
給定正整數序列x1,...,xn 。
(1)計算其最長不下降子串行的長度s。
(2)計算從給定的序列中最多可取出多少個長度為s的不下降子串行。
(3)如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長度為s的不下降子串行。
«程式設計任務:
設計有效演算法完成(1)(2)(3)提出的計算任務。
輸入格式:
第1 行有1個正整數n,表示給定序列的長度。接下來的1 行有n個正整數n:x1, ..., xn。
輸出格式:
第1 行是最長不下降子串行的長度s。第2行是可取出的長度為s 的不下降子串行個數。第3行是允許在取出的序列中多次使用x1和xn時可取出的長度為s 的不下降子串行個數。
輸入樣例#1: 複製
43 6 2 5
輸出樣例#1: 複製
223
500n≤500
最長不下降子串行
這個題目第一問顯然是lis
第二問和第三問就轉化成最大流。
轉化過程(理解了好久)
第二問:
建圖,先求出f陣列,f[i]表示到第i為的最長的不下降子串行,
然後因為第二問每乙個數只能用一次,所以就把乙個點拆成乙個入點乙個出點。
建圖就是讓f[i]==1的和s連在一起,f[i]==ans的和t連在一起,然後中間如果有
a[i]>=a[j]&&i>j&&f[i]=f[j]+1 這樣的話就把 j 的出點和 i 的入點連在一起,這個就是建圖過程。
接下來說說為什麼這麼建圖,
首先只考慮第二問,因為每乙個點只能用一次,所以就把點拆開,並且權值為1 ,然後因為只有f[i]==1
才會和s點相連,設f[i]==1的個數為x,所以這個就說明最多只能有x個答案,在這個基礎上再看有沒有從這個
點出發可以到達f[i]==ans的。
接下來說說為什麼會 a[i]>=a[j]&&i>j&&f[i]=f[j]+1 這個j的出點和i的入點連在一起。
這個必須是這樣子寫的,因為只有這個樣子到f[i]==ans 的過程中把中間的數字標記一次,不讓別的再跑了。
例如說樣例: 3 6 2 5 這個ans=2 第二問答案有兩組就是 3 6 和 2 5,
3和2都與源點連起來了,6和5 都和匯點連起來了,3也會和6 5 連起來,2就只會和6 連起來,
然後這個答案可以是3 5 或者2 6 和2 5 ,很顯然後面的才是最大流。
然後第三問 首先你要看清楚題目,題目說的只是x1和xn可以用無數多次,
所以這個就只要改成 s 到1 和1到n+1 和 n到 n+n if(f[n]==ans) n到 t 這些邊改成無數次然後就再跑一次。
因為f[i]==1所以從s到1很有可能會跑很多次,所以,這個既然x1可以用無數多次,則要設s到1和1到1+n為無數多次
如果f[n]!=ans 則說明這個點不會和t連在一起,所以就不能連n到t,但是n到n+n可以連無數多次,不過好像沒什麼用。
因為n是最後乙個
#include #include#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using
namespace
std;
const
int maxn =1e5;
ints, t;
struct
node
};vector
e;vector
g[maxn];
void add(int u,int v,int
w)int
a[maxn], dp[maxn];
intlevel[maxn], iter[maxn];
void bfs(int
s) }
}}int dfs(int u,int v,int
f) }
}return0;
}int
dinic()
}int
main()
res =max(res, dp[i]);
}printf(
"%d\n
", res);
for (int i = 1; i <= n; i++) add(i, i + n, 1
);
for (int i = 1; i <= n; i++) if (dp[i] == 1) add(s, i, 1
);
for (int i = 1; i <= n; i++) if (dp[i] == res) add(i+n, t, 1
);
for(int i=1;i<=n;i++)
}int ans =dinic();
printf(
"%d\n
", ans);
add(s,
1, inf);
add(
1, 1 +n, inf);
if (dp[n] == res) add(n, t, inf),add(n, n +n, inf);
int ech =dinic();
printf(
"%d\n
", ech+ans);
return0;
}
P2766 最長不下降子串行問題 題解(網路流)
最長不下降子串行問題 分成三小問解決。第一小問,求 lis 因為 n 500 直接 o n 2 暴力求解即可。第二三小問,建立模型用網路流求解。對於第二小問 1 首先,因為每個點只能使用一次,考慮拆點,把每乙個點拆成 i,n i 兩個點,從 i 連向 n i 一條長度為 1 的有向邊。2 其次,因為...
P2766 最長不下降子串行問題
話不多說,直接上思路。其實這就是一道dp動態規劃的經典問題,首先鏈上題目描述 問題描述 設有整數序列b1,b2,b3,bm,若存在 i1 i2 i3 in,且 bi1 bi2 bi3 bin,則稱b1,b2,b3,bm中有長度為n的不下降序列bi1,bi2,bi3,bin。求序列中最大不下降子串行長...
P2766 最長不下降子串行問題
問題描述 給定正整數序列x1,xn 1 計算其最長不下降子串行的長度s。2 計算從給定的序列中最多可取出多少個長度為s的不下降子串行。3 如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長度為s的不下降子串行。程式設計任務 設計有效演算法完成 1 2 3 提出的計算任務。輸入...