10.10离线赛
来源:互联网 发布:做篮球数据分析师就业 编辑:程序博客网 时间:2024/05/16 06:01
一、字符连通块
数据:对于70%,n、m∈[1,100]
对于100%,n、m∈[1,1000]
其实很简单,改变一个‘*’变成‘.’,那就会连通其上下左右四个点,那只要一开始判一下连通块,然后标记一下就行了。
二、回文字符序列
数据:对于30%,n∈[1,20]
对于60%,n∈[1,100]
对于100%,n∈[1,2000]
对于30%,可以二进制枚举,然后判选出来的点能否组成回文,这很简单。
后来我先用记忆化搜索,dp[L][R] 表示[L,R]区间内的方案数,然后每次对于一个[L,R]收集一下就行了。这个也不细讲。这样写可以过n∈[1,400]的
从记忆化搜索改成循环dp。按照上面的思想,定义dp[i][j] 表示长度为i起点为j的字符串的方案数。转移其实也很简单,玄学转移。
如果A[j]==A[j+i-1],即这段字符串两端相等,那就可以把中间的一段dp值加过来。
所有情况下,要把小区间的dp值转到大区间
#include<bits/stdc++.h>#define Mod 100007using namespace std;char A[2005],B[25];int n,dp[2005][2005];int main(){ scanf("%s",A+1); n=strlen(A+1); for(int i=1;i<=n;i++)dp[1][i]=1; for(int i=2;i<=n;i++) for(int j=1;j+i-1<=n;j++){ if(A[j]==A[j+i-1])dp[i][j]=(dp[i][j]+dp[i-2][j+1]+1)%Mod;//A[j]=A[j+i-1]的情况 dp[i][j]=(dp[i][j]+dp[i-1][j]+dp[i-1][j+1]-dp[i-2][j+1]+Mod)%Mod;//一般情况 } printf("%d\n",dp[n][1]);//从1开始长度为n return 0;}
三、删边最小生成树
数据:对于50%,n∈[1,300],m∈[1,3000]
对于100%,n∈[1,5000],m∈[1,200000]
一看完题觉得就和安全路径拿到一模一样。
先变成最小生成树,然后把树外面的边排个序每条边连进去,然后就会形成一个环。
然后每次更新完后把路径压缩一下,用并查集就行了,这样可以少更新一些边。这样就很快了。
其实写暴力也可以过,每次把连进去的边的两个端点一直往上走,边走边更新所有边。
#include<bits/stdc++.h>#define M 200005using namespace std;int n,m,len;struct node1{int x,y,v,id;}A[M];int Fa[M];bool Q[M];int find(int x) {return x==Fa[x]?x:Fa[x]=find(Fa[x]);}bool cmp(node1 a,node1 b){return a.v<b.v;}int fa2[3][M],dep[M],fa[M],ans[M];struct node2{int to,id,v;};vector<node2>edge[M];void f(int x,int fa1,int id,int v){ fa2[0][x]=fa1;fa2[1][x]=id;fa2[2][x]=v; dep[x]=dep[fa1]+1; for(int i=0;i<(int)edge[x].size();i++){ int y=edge[x][i].to; if(y==fa1)continue; f(y,x,edge[x][i].id,edge[x][i].v); }}int Find(int x){return x==fa[x]?x:fa[x]=Find(fa[x]);}int main(){ scanf("%d %d",&n,&m); for(int i=1;i<=m;i++)ans[i]=2e9; for(int i=1;i<=m;i++){scanf("%d %d %d",&A[i].x,&A[i].y,&A[i].v);A[i].id=i;} sort(A+1,A+m+1,cmp); for(int i=1;i<=n;i++)Fa[i]=i; for(int i=1;i<=m;i++){//先把最小生成树造出来 int x=A[i].x,y=A[i].y; int f1=find(x),f2=find(y); if(f1==f2)continue; edge[x].push_back((node2){y,A[i].id,A[i].v}); edge[y].push_back((node2){x,A[i].id,A[i].v}); len+=A[i].v;Q[A[i].id]=1;Fa[f1]=f2; } for(int i=1;i<=n;i++)fa[i]=i; f(1,0,0,0);//造树,并把树上的边的id,权值,端点处理出来 for(int i=1;i<=m;i++){ if(Q[A[i].id])continue;//只枚举不在树上的边 else { int x=A[i].x,y=A[i].y,v=A[i].v; while(x!=y){//往上走,并合并 if(dep[x]>dep[y]){ if(ans[fa2[1][x]]==2e9)ans[fa2[1][x]]=len-fa2[2][x]+v; fa[x]=fa2[0][x]; x=Find(x); }else{ if(ans[fa2[1][y]]==2e9)ans[fa2[1][y]]=len-fa2[2][y]+v; fa[y]=fa2[0][y]; y=Find(y); } } ans[A[i].id]=len;//更新 } } for(int i=1;i<=m;i++) if(ans[i]==2e9)printf("%d\n",-1); else printf("%d\n",ans[i]); return 0;}
差点就AK了,网站上对了,交上去却只有250啊…………
阅读全文
1 0
- 10.10离线赛
- 10.10离线赛总结
- 10.26离线赛题解
- 天池离线赛
- 天池离线赛
- 天池离线赛
- 天池离线赛
- 10.3离线赛
- 10.4离线赛
- 离线赛20171004总结
- 10.6离线赛
- 离线赛20171006总结
- 20171006离线赛总结
- 20171007离线赛总结
- 离线赛20171007总结
- 10.7离线赛
- 10.8离线赛
- 离线赛20171008总结
- 图片的三级缓存
- Coursera-Deep Learning Specialization 课程之(一):Neural Networks and Deep Learning-weak2
- JVM(3):Java GC算法 垃圾收集器
- 线程池的使用
- 三门问题(Monty Hall problem)简析
- 10.10离线赛
- LeetCode 12 Integer to Roman
- 关于异步的理解
- linux crontab 使用 注意事项
- 初学JS小记(三)——事件
- 网址收藏
- Django REST framework-API指南05-ViewSets 原创翻译
- JS中去掉字符串中的双引号
- 简单易懂的TCP/IP协议族