9.14 模拟赛
Posted Orion545
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了9.14 模拟赛相关的知识,希望对你有一定的参考价值。
模拟赛第三弹~
T1
题意:给你一个数列,要求删掉任意一种整数,使得剩下的新数列中连续的相等的数最多
例如 2 7 3 7 7 3 3 7 7 5 7,删掉3以后剩的7有四个连续的,最多
思路:暴力枚举去掉哪个......这算是一道水题吧
代码丢了...... TAT
T2
题意:有n本书,每本书有宽度和高度。现在你有无数个书架,每个书架的宽度为w,高度由最高的书决定
问在书本按顺序放的情况下,总的书架高度最小是多少
思路:dp,dp[i]表示做到第i本书时的最小高度和。
每次先找到能以编号j的书开始,编号i结束的一批书能放在同一个书柜里时,j的最小值,
然后枚举j到i-1,查找这一批书的最大值,dp[i]=min(dp[j]+max_height(h[j]~h[i]))
宽度前缀和,高度线段树
代码丢了*2
T3
题意:有一头牛,坐标(bx,by),n个柱子,横坐标都是cx,纵坐标是cy[i]
现在从牛身上开始有m段绳子,每个绳子有起点和终点坐标,绕在牛身上成为一圈
问最少拔掉几个柱子,能让牛逃走
思路:非常规题目,第一眼以为wind算法......
然而正解到现在都没看懂,挖坑*1
T4
题意:有n头牛(n<=20),每个牛有产奶量a[i],现在让你在所有牛中选出一部分,使得这些牛可以分成产奶量相同的两组
问:一共有多少种选择方法
思路:折半搜索(meet in the middle),先把两边的所有方法搜出来(状压方法表示),然后双指针维护,每次用位运算查看一下当前的合法状态是否已经算过
对于左边(i=1~n/2)和右边(i=n~n/2+1)的dfs,每次有三种情况:放在A组,放在B组,不选
这样最后只要看左边和右边dfs得出的所有情况里面,| Ai-Bi | (left) ==| Ai-Bi | (right) 的有多少组(不重复的)
代码(终于找到了!!!!):
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; struct node{ int s,x,next; }l[1100010],r[1100010]; int n,a[30],firstl[10010],firstr[10010],totl,totr; void dfs1(int k,int sum,int s){ if(k==n/2+1){ if(sum>=0){ l[++totl].s=s;l[totl].x=sum; l[totl].next=firstl[s];firstl[s]=totl; } return; } dfs1(k+1,sum,s); dfs1(k+1,sum+a[k],s|(1<<(k-1))); dfs1(k+1,sum-a[k],s|(1<<(k-1))); } void dfs2(int k,int sum,int s){ if(k==n/2){ if(sum>=0){ r[++totr].s=s;r[totr].x=sum; r[totr].next=firstr[s];firstr[s]=totr; } return; } dfs2(k-1,sum,s); dfs2(k-1,sum+a[k],s|(1<<(n-k))); dfs2(k-1,sum-a[k],s|(1<<(n-k))); } bool vis[5001000]={0}; bool cmp(node x,node y){ return x.x<y.x; } int main(){ int i,p1,p2,tmp1,tmp2,ans=0; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); dfs1(1,0,0);dfs2(n,0,0); sort(l+1,l+totl+1,cmp);sort(r+1,r+totr+1,cmp); p1=1;p2=1; while(p1<=totl&&p2<=totr){ if(l[p1].x>r[p2].x){ p2++;continue; } if(l[p1].x<r[p2].x){ p1++;continue; } tmp1=p1;tmp2=p2; while(l[p1].x==l[tmp1].x) p1++; while(r[p2].x==r[tmp2].x){ for(i=tmp1;i<p1;i++){ if(!vis[((r[p2].s)<<(n/2))|l[i].s]){ ans++;vis[((r[p2].s)<<(n/2))|l[i].s]=1; } } p2++; } } printf("%d",ans-1); }
总分:240+,自我感觉良好ing
然而对于代码实现(第四题)还是要加强啊......
以上是关于9.14 模拟赛的主要内容,如果未能解决你的问题,请参考以下文章