[网络流24题] 最长递增子序列
1|0731. [网络流24题] 最长递增子序列
★★★☆ 输入文件:
alis.in
输出文件:alis.out
简单对比时间限制:1 s 内存限制:128 MB
«问题描述:
给定正整数序列x1,..., xn。
(1)计算其最长递增子序列的长度s。
(2)计算从给定的序列中最多可取出多少个长度为s的递增子序列。
(3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长
度为s的递增子序列。
注意:这里的最长递增子序列即最长不下降子序列!!!
«编程任务:
设计有效算法完成(1)(2)(3)提出的计算任务。
«数据输入:
由文件alis.in提供输入数据。文件第1 行有1个正整数n(n<=500),表示给定序列的长度。接
下来的1 行有n个正整数x1,..., xn。
«结果输出:
程序运行结束时,将任务(1)(2)(3)的解答输出到文件alis.out中。第1 行是最长
递增子序列的长度s。第2行是可取出的长度为s 的递增子序列个数。第3行是允许在取出
的序列中多次使用x1和xn时可取出的长度为s 的递增子序列个数。
输入文件示例 输出文件示例
alis.in
4
3 6 2 5
alis.out
22
3
转载自hzwer
ps:任务3若能取出无限多的序列,则输出任务2的答案
- //数据略坑
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #define setfile(name) freopen(#name".in","r",stdin);freopen(#name".out","w",stdout);
- using namespace std;
- const int N=1005;
- const int inf=1e9;
- struct edge{int v,cap,next;}e[N*N*2];int tot=1,head[N];
- int n,S,T,K,ans,a[N],f[N],dis[N],q[N*N*2];
- inline int read(){
- int x=0,f=1;char ch=getchar();
- while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
- while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
- return x*f;
- }
- inline void add(int x,int y,int z){
- e[++tot].v=y;e[tot].cap=z;e[tot].next=head[x];head[x]=tot;
- e[++tot].v=x;e[tot].cap=0;e[tot].next=head[y];head[y]=tot;
- }
- inline bool bfs(){
- memset(dis,-1,sizeof dis);
- unsigned short h=0,t=1;q[t]=S;dis[S]=0;
- while(h!=t){
- int x=q[++h];
- for(int i=head[x];i;i=e[i].next){
- if(e[i].cap&&dis[e[i].v]==-1){
- dis[e[i].v]=dis[x]+1;
- if(e[i].v==T) return 1;
- q[++t]=e[i].v;
- }
- }
- }
- return 0;
- }
- int dfs(int x,int f){
- if(x==T) return f;
- int used=0,t;
- for(int i=head[x];i;i=e[i].next){
- if(e[i].cap&&dis[e[i].v]==dis[x]+1){
- t=dfs(e[i].v,min(e[i].cap,f));
- e[i].cap-=t;e[i^1].cap+=t;
- used+=t;f-=t;
- if(!f) return used;
- }
- }
- if(!used) dis[x]=-1;
- return used;
- }
- inline int dinic(){
- int res=0;
- while(bfs()) res+=dfs(S,inf);
- return res;
- }
- inline void DP(){
- for(int i=1;i<=n;i++){
- f[i]=1;
- for(int j=1;j<i;j++){
- if(a[i]>=a[j]){
- f[i]=max(f[i],f[j]+1);
- }
- }
- }
- K=*max_element(f+1,f+n+1);
- }
- void init(){
- n=read();
- for(int i=1;i<=n;i++) a[i]=read();
- }
- void ord_mapping(){
- tot=1;memset(head,0,sizeof head);
- for(int i=1;i<=n;i++){
- for(int j=1;j<i;j++){
- if(a[j]<=a[i]&&f[j]+1==f[i]){
- add(j+n,i,1);
- }
- }
- }
- }
- inline void work(){
- DP();printf("%d\n",K);
- S=0,T=n<<1|1;
- ord_mapping();
- for(int i=1;i<=n;i++){
- if(f[i]==1) add(S,i,1);
- if(f[i]==K) add(i+n,T,1);
- add(i,i+n,1);
- }
- ans=dinic();
- printf("%d\n",ans);
- ord_mapping();
- for(int i=1;i<=n;i++){
- int w=1;
- if(i==1||i==n) w=inf;
- if(f[i]==1) add(S,i,w);
- if(f[i]==K) add(i+n,T,w);
- add(i,i+n,w);
- }
- int lastans=ans;
- ans=dinic();
- if(ans>inf) printf("%d\n",lastans);
- else printf("%d\n",ans);
- }
- int main(){
- setfile(alis);
- init();
- work();
- return 0;
- }
__EOF__

本文作者:shenben
本文链接:https://www.cnblogs.com/shenben/p/6538561.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/shenben/p/6538561.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术