ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:43.50KB ,
资源ID:26891359      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/26891359.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Noip提高组Day2解题报告.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Noip提高组Day2解题报告.docx

1、Noip提高组Day2解题报告第二题:花匠(动态规划)1.令Si1表示以i为结尾,且降序到达ai的最长抖动序列长度;令Si0表示以i为结尾,且升序到达ai的最长抖动序列长度。依然设数组Si0/1,但考虑如下递推公式:(1)ai+1ai:Si+10=max(Si1+1,Si0);Si+11=Si1;(2)ai+1ai:Si+10=Si0;Si+11=max(Si0+1,Si1);(3)ai+1= =ai:Si+10=Si0;Si+11=Si1;S10=S11=1.算法优化后,再一次编写程序,O(n)的时间复杂度,当然是顺利AC了,代码如下:2.这道题明显可以用类似最长上升子序列的动态规划求解,易

2、得思路如下:用f(i,0)表示以i为结尾的且最后一段上升的子序列最大长度,f(i,1)表示表示以i为结尾的且最后一段下降的子序列最大长度,那么答案明显就是maxf(i,0),f(i,1)方程:f(i,0)=maxf(j,1)+1 0=ji且hjhif(i,1)=maxf(j,0)+1 0=jhi边界:f(0,0)=f(0,1)=0如果直接DP毫无疑问复杂度是O(n2),会TLE,但是,考虑到我们每次取最值时候取得都是一个区间里的数,如f(i,0)=maxf(j,1)+1 0=ji且hjhi取得就是区间0,hi-1里的最值,所以可以使用线段树或者是BIT(树状数组)来优化,这样复杂度就是O(n

3、log n),可以过全部数据。这道题还有一个解法,直接求拐点数目,然后就可以神奇的做到O(n)了,由于我找不到满意的证明,就不发上来了。代码(DP+BIT)(Cpp):#include #include #include using namespace std;#define MAXN 100010#define lowbit(x)(x)+1)&x)#define MAXH 1000010#define For(i,x) for (int i=x;i;i-=lowbit(i)#define rep(i,x) for (int i=x;i=maxh;i+=lowbit(i)int t0MAXH,

4、t1MAXH;int hMAXN,n,maxh=0;int fMAXN2,ans=0;void Add0(int x,int y) rep(i,x) t0i=max(t0i,y);void Add1(int x,int y) rep(i,x) t1i=max(t1i,y);int Max0(int x) int rec=0; For(i,x) rec=max(rec,t0i); return rec;int Max1(int x) int rec=0; For(i,x) rec=max(rec,t1i); return rec;int main() scanf(%d,&n); for (int

5、 i=0;i+n;) scanf(%d,&hi); maxh=max(maxh,+hi); fi0=fi1=1; maxh+; memset(t0,0,sizeof(t0),memset(t1,0,sizeof(t1); for (int i=0;i+n;) fi0=max(Max0(hi-1)+1,fi0); fi1=max(Max1(maxh-hi-1)+1,fi1); Add0(hi,fi1),Add1(maxh-hi,fi0); ans=max(ans,max(fi0,fi1); printf(%dn,ans); return 0;其实再进一步分析,发现问题可以简化成为求转折点数的问题

6、,又是一个O(n),对序列缩点,连续递减的点和连续递增的点是可以缩到一个代表性的点上的,比如说样例给的5 3 2 1 2,可以缩成5,1,2或3,1,2或2,1,2,即5 3 2这三个连续递减的点实际上可以由一个点代替,1是一个转折点,于是你也可以说是找转折点个数。第三题:华容道(最短路)这道题的数据范围是n=30,所以,我们可以看到,裸的O(n4)的BFS对于求解q较小的情况是无压力的,但是在q大的情况下,毫无疑问会TLE,明显,在q较大的情况下,我们需要将每次BFS中重复搜索的冗余信息除去,所以我们可以先分析题目性质:(这里称要移动的棋子为目标棋子)首先,如果要移动目标棋子,那么我们首先必

7、须要将空格移到该棋子的上下左右四个方向上相邻位置之一,然后才可以移动该棋子。然后,我们分析该棋子移动时候的性质:棋子每次可以移动,仅当空格位于其相邻位置的时候,每次移动完棋子,空格总会在棋子相邻的位置,那么我们发现,对于棋子在某一位置,然后空格又在其四个方向上某一相邻位置时,棋子要想某一方向移动一个时的花费的步数是一定的,那么,就可以先进行一次预处理,预处理出对于目标棋子在上述条件下每次移动所需的步数。然后,预处理完成之后,我们会发现每次查询都会变成一个求最短路的问题,用Dijstra或SPFA的话,可以在时限范围内解决。实现:定义一个数组Stepxykh,表示目标棋子在位置(x,y)且空格在

8、目标棋子的k方向上的相邻格子时,目标棋子往h方向移动1格所需的步数,然后用状态xyk作为节点建图,用各个状态的关系连边,每次询问时重新定义一个源点跟终点,跑最短路就可以得出答案。(预处理时跑n2次O(n2)的BFS就可以了)复杂度(Dijstra):(n4+n2 log n)复杂度(SPFA):(n4+n2)代码(SPFA)(Cpp):#include #include #include #include using namespace std;#define MAXN 32#define MAXV 50010#define inf (1t=t,p-d=d; p-next=heads; hea

9、ds=p;int MapMAXNMAXN,n,m,q,ex,ey,sx,sy,tx,ty;int vMAXNMAXN4,V=0;int distMAXNMAXN,MoveMAXNMAXN44;int DistMAXV;bool fMAXV;int S,T;struct node int x,y; node (int _x,int _y):x(_x),y(_y) ;queueQ;int Bfs(int Sx,int Sy,int Tx,int Ty) if (Sx=Tx&Sy=Ty) return 0; while (!Q.empty() Q.pop(); for (int i=0;i+n;)

10、for (int j=0;j+m;) distij=inf; distSxSy=0; Q.push(node(Sx,Sy); while (!Q.empty() node u=Q.front(); Q.pop(); for (int i=0;iDisty; ;priority_queueint,vector,CmpPq;int spfa() for (int i=0;i+next) if (Distp-tDistu+p-d) Distp-t=Distu+p-d; fp-t=true; Pq.push(p-t); return DistTnmq; memset(Map,0,sizeof(Map)

11、; for (int i=0;i+n;) for (int j=0;j+Mapij; for (int k=0;k4;k+) vijk=+V; for (int i=0;i+n;) for (int j=0;j+m;) for (int k=0;k4;k+) for (int h=0;h4;h+) Moveijkh=inf; for (int i=0;i+n;) for (int j=0;j+m;) if (Mapij) Mapij=0; for (int k=0;k4;k+) if (Mapi+dirk0j+dirk1) for (int h=0;h4;h+) if (Mapi+dirh0j

12、+dirh1) Moveijkh=Bfs(i+dirk0,j+dirk1,i+dirh0,j+dirh1)+1; Mapij=1; memset(head,0,sizeof(head); for (int i=0;i+n;) for (int j=0;j+m;) for (int k=0;k4;k+) for (int h=0;h4;h+) if (Moveijkhexeysxsytxty; if (sx=tx&sy=ty) cout0endl; continue; S=+V; T=+V; if (Mapsxsy=0|Maptxty=0) cout-1endl; continue; Mapsxsy=0; for (int i=0;i4;i+) if (Mapsx+diri0sy+diri1) int D=Bfs(ex,ey,sx+diri0,sy+diri1); if (Dinf) AddEdge(S,vsxsyi,D); Mapsxsy=1; for (int i=0;i4;i+) if (Maptx+diri0ty+diri1) AddEdge(vtxtyi,T,0); coutspfa()endl; return 0;

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1