题目链接:戳我

我们先做一个DP,就能求出来到前i位的最长上升子序列的长度(maxx[i]数组)。

然后我们考虑求最小割——给每个点拆点,如果要割掉这个点,就相当于把in[i]--out[i]这条边给割掉了。

然后如果在最长上升子序列中,该位下面可以接很多,那么就从该位代表的out向下面可以接的in连边。

然后跑最小割就行了QAQ

但是......之后还需要求字典序最小的最小割方案。
那么我们先把边从小到大排个序,然后把所有可能割边都捞出来,贪心地选择。
但是有一个问题,就是我们选择了一个边之后,它会对我们之后的决策产生影响(比如说,本来应该选的边可以不选了)
所以我们要强行退流(具体操作可以看代码)。我们知道选了这条边之后,这条边的可替代品就不需要选了,这些可替代它的边显然是存在于S-u,v-T之间的。所以我们直接退掉他们满流边的流量就行啦!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define S 0
#define T 2*n+1
#define MAXN 1510
#define INF 0x3f3f3f3f
using namespace std;
inline int read()
{int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch==-1)f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
}
int TT,n,t=1,cnt,kkk;
int num[MAXN];
int ans[MAXN],in[MAXN],out[MAXN],done[MAXN];
int head[MAXN],cur[MAXN],dis[MAXN],dp[MAXN][MAXN],maxx[MAXN];
struct Node{int id,a,b,c;}node[MAXN];
struct Edge{int nxt,to,dis;}edge[MAXN*MAXN*2];
inline void add(int from,int to,int dis)
{
//  printf("[%d %d] %d\n",from,to,dis);edge[++t].nxt=head[from],edge[t].to=to,edge[t].dis=dis,head[from]=t;edge[++t].nxt=head[to],edge[t].to=from,edge[t].dis=0,head[to]=t;
}
inline bool check(int s,int t)
{queue<int>q;memset(done,0,sizeof(done));q.push(s);done[s]=1;while(!q.empty()){int u=q.front();q.pop();if(u==t) return true;for(int i=head[u];i;i=edge[i].nxt){int v=edge[i].to;if(edge[i].dis&&done[v]==0) q.push(v),done[v]=1;}}return false;
}
inline bool bfs(int s,int t)
{queue<int>q;memset(dis,0x3f,sizeof(dis));memcpy(cur,head,sizeof(head));q.push(s);dis[s]=0;while(!q.empty()){int u=q.front(); q.pop();for(int i=head[u];i;i=edge[i].nxt){int v=edge[i].to;if(edge[i].dis&&dis[v]==0x3f3f3f3f){dis[v]=dis[u]+1;q.push(v);}}}if(dis[t]==0x3f3f3f3f) return false;return true;
}
inline int dfs(int x,int t,int f)
{if(!f||x==t) return f;int used=0,w;for(int i=cur[x];i;i=edge[i].nxt){int v=edge[i].to;cur[x]=i;if(dis[v]==dis[x]+1&&(w=dfs(v,t,min(edge[i].dis,f)))){edge[i].dis-=w;edge[i^1].dis+=w;used+=w,f-=w;if(!f) break;}}return used;
}
inline int dinic(int s,int t)
{int cur_ans=0;while(bfs(s,t)) cur_ans+=dfs(s,t,INF);return cur_ans;
}
inline void pre()
{for(int i=1;i<=n;i++){maxx[i]=1;for(int j=1;j<i;j++)if(node[i].a>node[j].a)maxx[i]=max(maxx[i],maxx[j]+1);}   for(int i=1;i<=n;i++) kkk=max(kkk,maxx[i]);
}
inline void add_edge()
{for(int i=1;i<=n;i++) in[i]=i;for(int i=n+1;i<=2*n;i++) out[i-n]=i;for(int i=1;i<=n;i++) add(in[i],out[i],node[i].b),num[i]=t-1;for(int i=1;i<=n;i++){for(int j=1;j<i;j++){if(maxx[j]+1==maxx[i]&&node[j].a<node[i].a)add(out[j],in[i],INF);}}for(int i=1;i<=n;i++) if(maxx[i]==1) add(S,in[i],INF);for(int i=1;i<=n;i++) if(maxx[i]==kkk) add(out[i],T,INF);
}
inline bool cmp(struct Node x,struct Node y){return x.c<y.c;}
inline void solve()
{for(int i=1;i<=n;i++){int x=node[i].id;if(check(in[x],out[x])) continue;ans[++cnt]=x;while(bfs(T,out[x])) dfs(T,out[x],INF);while(bfs(in[x],S)) dfs(in[x],S,INF);edge[num[x]].dis=0,edge[num[x]^1].dis=0;}
}
int main()
{#ifndef ONLINE_JUDGEfreopen("ce.in","r",stdin);#endifTT=read();while(TT--){memset(head,0,sizeof(head));cnt=0,kkk=0;t=1;n=read();for(int i=1;i<=n;i++) node[i].a=read();for(int i=1;i<=n;i++) node[i].b=read();for(int i=1;i<=n;i++) node[i].c=read();pre();add_edge();printf("%d ",dinic(S,T));for(int i=1;i<=n;i++) node[i].id=i;sort(&node[1],&node[n+1],cmp);solve();printf("%d\n",cnt);sort(&ans[1],&ans[cnt+1]);for(int i=1;i<=cnt;i++) printf("%d ",ans[i]); puts("");}return 0;
}

转载于:https://www.cnblogs.com/fengxunling/p/11005895.html

SDOI2014 LIS相关推荐

  1. bzoj千题计划141:bzoj3532: [Sdoi2014]Lis

    http://www.lydsy.com/JudgeOnline/problem.php?id=3532 如果没有字典序的限制,那么DP拆点最小割即可 加上字典序的限制: 按c从小到大枚举最小割边集中 ...

  2. [bzoj3532][Sdoi2014]Lis

    来自FallDeram的博客,未经允许,请勿转载,谢谢. 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若项,使得4的最长上升子序列长度减少至少1,且付出的代价之和最小,并输出方案 ...

  3. 做题记录 To 2019.2.13

    2019-01-18 4543: [POI2014]Hotel加强版:长链剖分+树形dp. 3653: 谈笑风生:dfs序+主席树. POJ 3678 Katu Puzzle:2-sat问题,给n个变 ...

  4. bzoj 乱刷计划 50/50

    前言 话说第一个板刷计划由于种种原因而告一段落了..其实那一版还有很多题想做,那就只能放一放了 附上效果图一张(几乎每一题都在我博客有题解): 打算 可以复习,重做自己做过的题,不局限于没做过的 乱刷 ...

  5. UVa 10051 Tower of Cubes(类似LIS)

    题意: 一些重量递增而且各个面都有颜色的立方体,要将这些立方体堆成一个塔,要求两个接触面同色,而且下面的立方体更重.求塔的最大高度. 思路: 用求LIS的思想,无非是多了几个状态.dp[i][j]表示 ...

  6. 1045 Favorite Color Stripe(LIS解法)

    解题思路 本题属于Longest Increasing Sequence最长不下降子序列,但是要注意,LIS当中不会有无效的元素,而本题是有的,所以先要把无效元素过滤掉,才能转化成为LIS问题. 这里 ...

  7. LIS ZOJ - 4028

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4028 memset超时 这题竟然是一个差分约束 好吧呢 对于每一个a[i] ...

  8. 【hdu】4521 小明序列【LIS变种】【间隔至少为d】

    题目链接:https://vjudge.net/contest/228455#problem/B 转载于:https://blog.csdn.net/a709743744/article/detail ...

  9. HDU 1257 - 最少拦截系统 ( LIS / 贪心 )

    题目 现在有一种拦截系统,第一发拦截可以是任意高度,但是之后的拦截高度不能比上次高.为了拦截下所有的炮弹,最少需要准备几套拦截系统? 思路 可能是语文没学好吧,一开始被题意卡了一下.(而且题目连数据范 ...

最新文章

  1. awk 抓取文件子集
  2. 利用Mircosoft URLRewriter.dll实现asp.net页面伪静态
  3. Algorithm之PGM之BNet:贝叶斯网络BNet的相关论文、过程原理、关键步骤等相关配图
  4. 全球及中国医疗监护仪市场容量需求与投资竞争力研究报告2022版
  5. 设置 tableview 的背景颜色,总是不生效
  6. CSS 如何让 height:100%; 起作用
  7. 实验:PIO外部中断
  8. 联想将在CES上展示LePad平板
  9. 印发 指南 通知_通知设计的综合指南
  10. Spring注解和XML配置文件孰优孰劣
  11. html页面上显示拼音
  12. qpsk调制matlab仿真,QPSK调制解调仿真
  13. AirDisk-Q3C/T2/Q3S/Q3X加密空间PIN码忘记怎么找回?
  14. 初学者如何选择适合自己的吉他?0基础新手男女生吉他推荐
  15. 计算机机房门尺寸,门的宽度是多少
  16. 【2017 BSUIR Semifinal D】Friends rescue 题解
  17. 最新微软薪资曝光,Run去美国还是好选择吗?
  18. IT人需要了解的认证大全(持续补充)
  19. 【学算法的辅助练习1】北大POJ2388:Who‘s in the Middle
  20. ESFP型人格的爱情分析,ESFP型人格的职业分析

热门文章

  1. ztree.js的使用整理
  2. 2016年宜昌楼市将迎来史上最激烈一战
  3. Qt 5.5增加了新的GL模块,并改进了跨平台支持
  4. runtime运行时编程一些相关知识
  5. nginx处理web请求分析
  6. windows下使用lighttpd+php(fastcgi)+mysql
  7. IIS中保持HTTP连接
  8. DHCP服务器的搭建
  9. Strategy模式与Delegate委托
  10. [NOI2017]游戏(2-SAT)