[网络流24题]最长上升子序列问题
来源:互联网 发布:登陆淘宝卖家中心 编辑:程序博客网 时间:2024/05/29 19:17
PowerOj1741
对于第一个小问我们可以跑一遍dp,求得ans1,和f[]数组,f[i]表示以i结尾的最长上升子序列
对于第二问和第三问,我们考虑把第i个数拆成两个点,ai与bi。
考虑这样建边:
1. 连接ai,bi,限制为1的边
2. 如果f[i]等于ans1,那么连接bi,t,限制为1的边
3. 如果f[i]等于1,连接s,ai,限制为1的边
4. 如果f[i]=f[j]+1且a[i]>a[j],连接一条bj,ai,限制为1的边
对于第二问,我们跑一遍最大流就是答案了。
对于第三问,我们考虑把
#include<iostream> #include<iomanip> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 5010 #define ll long long using namespace std; struct node{ int to,f,m; node*next,*rev; }*con[maxn]; int dl[maxn],head,tail,de[maxn]; int n,a[maxn],s,t,v; bool tag[maxn]; void addedge(int x,int y,int m) { node*p=new node; p->to=y; p->f=0; p->m=m; p->next=con[x]; con[x]=p; p=new node; p->to=x; p->f=0; p->m=0; p->next=con[y]; con[y]=p; con[x]->rev=con[y]; con[y]->rev=con[x]; } bool bfs() { bool tmp=false; head=1;tail=0; dl[++tail]=s; memset(de,0,sizeof(de)); de[s]=1; while(head<=tail) { v=dl[head]; if(v==t) tmp=true; for(node*p=con[v];p;p=p->next) if(p->f<p->m&&de[p->to]==0) dl[++tail]=p->to,de[p->to]=de[v]+1; head++; } return tmp; } int dinic(int v,ll e) { ll o=0,temp=0; if(v==t) return e; if(tag[v]) return 0; for(node*p=con[v];p;p=p->next) { if(de[p->to]==de[v]+1&&p->f<p->m) { o=dinic(p->to,min((int)e-(int)temp,(int)p->m-p->f)); temp+=o; p->f+=o; p->rev->f-=o; } if(temp==e) break; } if(temp==0) tag[v]=true; return temp; } int f[maxn]; int ans1=0; int main() { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); for(int i=1;i<=n;++i) f[i]=1; for(int i=1;i<=n;i++) { f[i]=1; for(int j=1;j<i;j++) if(a[j]<=a[i])f[i]=max(f[i],f[j]+1); ans1=max(ans1,f[i]); } cout<<ans1<<endl; s=0;t=2*n+1; for(int i=1;i<=n;++i) { if(f[i]==1) addedge(s,i,1); if(f[i]==ans1) addedge(i+n,t,1); addedge(i,i+n,1); } for(int i=1;i<n;++i) for(int j=i+1;j<=n;++j) if(a[j]>=a[i]&&f[j]==f[i]+1) addedge(i+n,j,1); ll ans2=0; while(bfs()) { memset(tag,0,sizeof(tag)); ans2+=dinic(s,0x3f3f3f3f); } cout<<ans2<<endl; for(node*p=con[1];p;p=p->next) if(p->to==n+1) p->m=0x3f3f3f3f; for(node*p=con[n];p;p=p->next) if(p->to==2*n) p->m=0x3f3f3f3f; for(node*p=con[s];p;p=p->next) if(p->to==1) p->m=0x3f3f3f3f; for(node*p=con[2*n];p;p=p->next) if(p->to==t) p->m=0x3f3f3f3f; while(bfs()) { memset(tag,0,sizeof(tag)); ans2+=dinic(s,0x3f3f3f3f); } cout<<ans2<<endl; }
阅读全文
0 0
- [网络流24题]最长上升子序列问题
- HDU_3998_Sequence(最长上升子序列 + 网络流)
- 最长上升子序列问题
- 最长上升子序列问题
- 最长上升子序列问题
- 最长上升子序列问题
- 最长上升子序列问题
- 最长上升子序列问题
- 最长上升子序列问题
- 最长上升子序列问题
- [网络流24题 #6]最长递增子序列问题
- 【网络流24题】最长不下降子序列问题
- 网络流24题之最长递增子序列问题
- 【网络流24题】最长递增子序列问题
- 【codevs1906】[网络流24题]最长递增子序列问题
- 网络流24题6. 最长递增子序列问题
- 网络流24题:最长递增子序列问题
- HDU 3998 Sequence 最长上升子序列+网络流 求不相交的最长上升子序列个数
- PullToRefresh和TableLayout,fragment的联合使用
- python利用unitest生成的报告如何输出为html
- 机器学习作用于信息安全的五大顶级案例
- 李飞飞:人工智能应用广泛 但场景理解不如2岁孩子
- AAC ADTS格式分析
- [网络流24题]最长上升子序列问题
- 频道管理++
- Neutron 的物理部署方案(4)
- First--layout
- Spring 与 SpringMVC 容器父子关系引出的相应问题
- phpstorm安装bootstrap插件
- Openwrt /etc/config/network 配置解析
- 属性动画+购物车+结算
- Toad查询显示Oracle 表中的RowId