[HAOI2017模拟]囚人的旋律
没有传送门辣。
神奇的DP题。
首先看到这道题第一眼应该想到正解不是在图上搞,肯定要把原图转化成序列。
根据逆序对的性质。每个点和标号大于他的点连边的点,其权值必定要小于该点,而没和他连边的且标号大于他的点,权值也必定大于他。
根据这个,我们就可以递增的枚举标号,每次判定该点和几个标号大于他的点连右边,即确定在未被选的权值里有多少个点比他小。
然后就可以确定当前点的标号了。
这样就成功的把原图转化成了序列。
接下来考虑在序列上做DP。
很显然,如果选中的一些点是满足要求的。必然要满足其构成一个上升子序列,只有上升子序列的点集才是题目所称的独立集。
覆盖集就不是那么好处理了。假设我们已经选定了一堆点,那么对于未选定的点,必定和其中某一个点构成逆序对。用数学公式表示一下就是这样的:
$\forall a_i \notin V_1$,必定$\exists a_j \in V_2$使得$a_i>a_j$且$i<j$或者$a_i<a_j$且$i>j$。
那么接下来考虑序列上的一个片段$(L,R)$,其中$L,R$都是已经被钦定的点。那么对于在$(L,R)$中的所有点$a_i$,一定不满足$a_L \leq a_i \leq a_R$。
但是不能存在一个点满足上述条件但是和之前的点存在逆序对关系吗?
考虑一个点满足上述条件。那么另一个被钦定的点要么大于$a_L$,要么小于$a_R$,这样就不满足独立集的关系了。
所以根据这个做DP即可。
即设$f[i]$表示以$i$结尾的方案数,加一些小优化即可满足$O(N^2)$的复杂度。
//senritsu //by Cydiater //2017.1.17 #include <iostream> #include <queue> #include <map> #include <ctime> #include <cstring> #include <string> #include <iomanip> #include <ctime> #include <algorithm> #include <cstdlib> #include <cstdio> #include <bitset> #include <set> #include <vector> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) #define cmax(a,b) a=max(a,b) #define cmin(a,b) a=min(a,b) #define Auto(i,node) for(int i=LINK[node];i;i=e[i].next) #define FILE "senritsu" const int MAXN=1e4+5; const int oo=0x3f3f3f3f; const int mod=1000000007; inline int read(){ char ch=getchar();int x=0,f=1; while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int N,M,LINK[MAXN],len=0,arr[MAXN],f[MAXN]; bool used[MAXN]; struct edge{ int y,next; }e[MAXN<<10]; namespace solution{ inline void insert(int x,int y){ e[++len].next=LINK[x];LINK[x]=len;e[len].y=y; } inline void Insert(int x,int y){ insert(x,y); insert(y,x); } void Prepare(){ N=read();M=read(); up(i,1,M){ int x=read(),y=read(); Insert(x,y); } up(i,1,N){ int cnt=0,K=0; Auto(j,i)if(e[j].y>i)cnt++; up(j,1,N)if(!used[j]){ K++; if(K==cnt+1){ used[j]=1; arr[i]=j; break; } } } arr[0]=-oo;arr[N+1]=oo-1; } void Solve(){ int Min; f[0]=1; up(i,0,N+1){ Min=oo; up(j,i+1,N+1){ if(arr[j]>arr[i]&&Min>arr[j])(f[j]+=f[i])%=mod; if(arr[j]>arr[i])cmin(Min,arr[j]); } } cout<<f[N+1]<<endl; } } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); using namespace solution; Prepare(); Solve(); return 0; }
[HAOI2017模拟]囚人的旋律的更多相关文章
- bzoj4715 囚人的旋律
4715: 囚人的旋律 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 74 Solved: 48[Submit][Status][Discuss] ...
- 【BZOJ4715】囚人的旋律
题解: 思考了很久这个图的特点没有发现 看了题解瞬间醒悟原来要在序列上做 还原出这张图显然是O(N^2)可以做的 然后其实就比较简单了 首先为了满足独立集,我们需要保证所取元素递增 为了满足覆盖集,我 ...
- 【bzoj4715】囚人的旋律 dp
题目描述 给你一个 $1\sim n$ 的排列 $a_i$ ,若 $i\le j$ 且 $a_i\ge a_j$ ,则 $i$ 到 $j$ 有一条边.现在给你这张图,求既是独立集(任意两个选定点都没有 ...
- [HAOI2017模拟]百步穿杨
今天的考试题. 考试的时候因为以前做过还写过题解,然后就以为模型已经很清楚了,然后就开始直接推.最后因为蜜汁自信一定能推出来,然后模型搞错了,只能交个暴力上去,于是这场考试GG. 第一次碰上这道题是在 ...
- unity3d Human skin real time rendering 真实模拟人皮实时渲染(转)
先放出结果图片...由于网上下的模型是拼的,所以眼皮,脸颊,嘴唇看起来像 存在裂痕,解决方式是加入曲面细分和置换贴图 进行一定隆起,但是博主试了一下fragment shader的曲面细分,虽然细分成 ...
- unity3d Human skin real time rendering 真实模拟人皮实时渲染
先放出结果图片...由于网上下的模型是拼的,所以眼皮,脸颊,嘴唇看起来像存在裂痕,解决方式是加入曲面细分和置换贴图 进行一定隆起,但是博主试了一下fragment shader的曲面细分,虽然细分成功 ...
- git 学习(3) ----- 代码共享和多人协作
当我们开发项目的时候,项目会越来越大,就有可能需要其它同事进行参与,甚至进行开源,这时就需要找一个地方把代码存放起来,好供其它人下载并开发.这个地方,最好放到服务器上,因为只要能上网,就可以获取到, ...
- Netty多人聊天室
在简单聊天室的代码中修改ChatServerHandler类,就可以模拟多人聊天的功能 package com.cppdy.server; import io.netty.channel.Channe ...
- webrtc笔记(5): 基于kurento media server的多人视频聊天示例
这是kurento tutorial中的一个例子(groupCall),用于多人音视频通话,效果如下: 登录界面: 聊天界面: 运行方法: 1.本地用docker把kurento server跑起来 ...
随机推荐
- c#基础 第五讲
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- Maven开发系统
Maven的优点: 自动从互联网中获取jar包,并实现了一步构建. pom.xml的配置 依赖管理(导入对应的jar包) 通过坐标(定位到仓库中的包的位置,并将jar包导入到项目中,如果版本升级,只需 ...
- 170411、java Socket通信的简单例子(UDP)
服务端代码: package com.bobohe.socket; import java.io.*; import java.net.*; class UDPServer { public stat ...
- Storm 在ZK 上的目录图
这是Zk 的可视化工具 看到的Storm 目录结构 ,这时候没有提交任何的任务给这个集群, 其实这时候我只是启动了 nimbus 还没有启动Supervisors ,所有你 看懂的Superviso ...
- 移动端click时间、touch事件、tap事件
一.click 和 tap 比较 两者都会在点击时触发,但是在手机WEB端,click会有 200~300 ms,所以请用tap代替click作为点击事件. singleTap和doubleTap 分 ...
- 给NavigationBar设置颜色
传统的设置 ) { [[UINavigationBar appearance] setBarTintColor:[UIColor redColor]]; } else { [[UINavigation ...
- 多进程使用matplotlib.pyplot绘heatmap(多线程不可以)
数据格式如下: 8_15/l_eye/2732.png -20.5773 -5.17769 -3.34583 21.5859 9_13_1/l_eye/1211.png -10.1145 34.992 ...
- 13.Query for Null or Missing Fields-官方文档摘录
1 插入数据 db.inventory.insertMany([ { _id: 1, item: null }, { _id: 2 } ]) 2 查询null值 db.inventory.find({ ...
- FindBugs——帮助查找隐藏的bug
FindBugs 1.什么是FindBugs FindBugs 是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题.有了静态分析工具,就可以在不实际运行程序 ...
- 单舵轮(叉车)AGV里程计数据解算
单舵轮(叉车)AGV里程计数据解算 2016-07 单舵轮AGV,一般包含一个驱动轮和两个从动轮,驱动轮是同时具备行走和转向两个功能的舵轮,因此,单舵轮AGV的运动学自由度为2个.舵轮线速度V1,舵轮 ...