[luogu 2766] 最長不下降子串行問題
傳送門第一問:
\(o(n^2)\) 的dp求lis
為了下面敘述方便,我們將dp過程講一遍
子狀態:dp[i]表示以a[i]結尾的lis長度
初始條件:dp[i]=1
狀態轉移方程:\(dp[i]=dp[j]+1(j
第二問:
我們發現若a[j]加上a[i]可以構成乙個不下降子串行,則\(j
又發現每個元素只能在乙個序列中,考慮拆點
建圖方法:
原點s=0,t=2n+1
(1)每個點拆成兩個點,i向i+n連邊,容量1
(2)如果dp[i]=1,則s向i連邊,容量1
(3)如果\(j,則j+n向i連邊,容量1
(4)如果dp[i]=k(k為lis長度),則i+n向t連邊,容量1
最大流即為答案
第三問:
除了1和n對應節點有關的邊容量為inf,其他建圖和方案二一樣
注意一種特殊情況需要特判
當序列嚴格遞減時,dp[i]=1,s=1,並且不存在i,j滿足\(j
由於dp[1]=1=k,則s會向1連一條inf的邊,1向1+n連一條inf的邊,1+n向t連一條inf的邊,最大流為inf
此時第三問的答案應等於第二問,為n
#include#include#include#include#define maxn 505
#define maxm 500005
#define inf 0x3f3f3f3f
using namespace std;
int n;
struct edgee[maxm<<1];
int sz=1;
int head[maxn*2];
void add_edge(int u,int v,int w)
int deep[maxn*2];
bool bfs(int s,int t)}}
return 0;
}int dfs(int x,int t,int minf)
}return minf-rest;
}int dinic(int s,int t)
return maxflow;
}int len;
int a[maxn];
int dp[maxn];
int solve1()
}ans=max(ans,dp[i]);
}return ans;
}int solve2()
for(int i=1;i<=n;i++)
for(int i=1;i<=n;i++)} }
for(int i=1;i<=n;i++)
} return dinic(s,t);
}bool is_decrease()
return 1;
}int solve3()
}for(int i=1;i<=n;i++)
for(int i=1;i<=n;i++)} }
for(int i=1;i<=n;i++)
} return dinic(s,t);
}int main()
len=solve1();
printf("%d\n",len);
printf("%d\n",solve2());
printf("%d\n",solve3());
}
網路流24題之最長不下降子串行
對於第一問直接n 2dp計算 第二問建圖跑網路流 第三問將起始與結尾流量開大 建邊的時候要嚴格按照子串行求法建 by 大奕哥 1 include2 using namespace std 3const int n 10005 4 inthead n d n f n a n 5int n,m,cnt ...
網路流24題 最長不下降子串行問題
傳送門 here 題意 給定正整數序列 x 1,x n 1 計算其最長不下降子串行的長度s。2 計算從給定的序列中最多可取出多少個長度為s的不下降子串行。3 如果允許在取出的序列中多次使用 x 1 和 x n 則從給定序列中最多可取出多少個長度為 s 的不下降子串行。思路分析 題意首先就很坑 注意第...
網路流24題 最長不下降子串行問題(最大流)
題目鏈結 這個題目有三個要求出來的 計算其最長不下降子串行的長度s。計算從給定的序列中最多可取出多少個長度為s的不下降子串行 如果允許在取出的序列中多次使用x1和xn,則從給定序列中最多可取出多少個長度為s的不下降子串行 自己的想法 對於 問題1 直接用那個動態規劃去跑下,就求出答案len了,這是會...