省选模拟3.22

T1

考场上分析出了几个性质,觉得是个贪心/DP结果从贪心耽误太久了,dp没有细想

还是说dp[i]表示前i个子图的满足情况的最小价值

怎么说,考场上想到的那个贪心就是这个,然后我对于区间操作就卡了,好吧,我还是稍逊一些

还是说,我们转移的时候,先看一下,我们这一段的右端点在哪

那么就可以分块转移了

其实只有两种转移吧,一个是后面直接连前面,或者目前点直接连最远点

目前点到最远点之间会存在断点使得使得两边断掉,那么还是一个个转移就好了

在思考一下

其实本质过程是分段,n3的话很好说

我们考虑优化掉一维dp[i]表示前i个分成若干段代价的最小值,考虑i>j

那么就很好说了

首先我们对于这一部分,我们现在是l,我们对于我们目前可达右端点,必然是枚举当前是否为断点去判断

我们往后更新的话,需要更新一下连边情况,如果当前点,没有被打标记,其余的区间赋值,没有连边的都连上就好了,或者更新下一步能不能断点就好了,挺神的

#include<cstring> #include<vector> #include<cstdio> using namespace std; int n,m,in1,in2,dp[200010]; vector<int>ed[200010];bool vis[200010]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d",&in1,&in2); ed[min(in1,in2)].push_back(max(in1,in2)); } memset(dp,0x3f,sizeof(dp)); dp[1]=0; for(int l=1,r=1,cn=0;l<=n;l++) { if(!vis[l])cn++; for(vector<int>::iterator ite=ed[l].begin();ite!=ed[l].end();ite++) { r=max(r,*ite); if(!vis[*ite]) cn++,vis[*ite]=true; } r=max(r,l+1); dp[r]=min(dp[r],dp[l]+r-cn); if(l!=1)dp[l+1]=min(dp[l+1],dp[l]+1); } printf("%d",dp[n]);return 0; }

 

T2

考场上想到了前两步,1,2起手,然后不会往后延伸了

只有HH和我一样...

那么以示尊敬,1,2起手

然后对于后面来说,我们对于目前点都能到的点都连100

最优解的话,我们保证都有一条向上的1

跑出来的是这样走1>2>3>5/1>4>6

最优解的话可以1>2>4>5>8>9/1>3>6>7

就是隔一个跨三个,然后一个连后面

大概就是走一步走三步这样就好了

T3

上午最短路写成大根堆了QAQ

//没处理向下的 //用脑子想一想 //出现问题的只有前面一部分,如果那么只需要H和dis取个max就好了 //其实也就是,前面的dis如果不大于H,证明前面这部分还有剩余 //其实就是看这个影响的部分,首先我们不需考虑往上的代价,只需要考虑往下和前进的代价的代价 //如果我们前面的距离不足到的话,我们就需要取个max //dis的两种更新方式罢了 #include<bits/stdc++.h> #define INF 0x3f3f3f3f3f3f3f3f #define int long long #define MAXN 6000005 using namespace std; int head[MAXN],nxt[MAXN],val[MAXN],dis[MAXN],to[MAXN],h[MAXN],tot,H,n,m; priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q; bool vis[MAXN]; void add(int u,int v,int w) { tot++; to[tot]=v; val[tot]=w; nxt[tot]=head[u]; head[u]=tot; } void dij() { memset(dis,0x3f,sizeof(dis)); dis[1]=0; q.push(make_pair(dis[1],1)); while(!q.empty()) { int now=q.top().second; q.pop(); if(vis[now]) continue; vis[now]=true; for(int i=head[now];i;i=nxt[i]) { int y=to[i]; int w=dis[now]+val[i]; if(H>h[y]) w=max(w,H-h[y]); if(dis[y]>w) { dis[y]=w; q.push(make_pair(dis[y],y)); } } } if(dis[n]==INF) { puts("-1"); exit(0); } cout<<2*dis[n]-H+h[n]; } int u,v,w; signed main() { cin>>n>>m>>H; for(int i=1;i<=n;i++) { cin>>h[i]; } for(int i=1;i<=m;i++) { cin>>u>>v>>w; if(h[u]>=w) add(u,v,w); if(h[v]>=w) add(v,u,w); } dij(); }

 


__EOF__

本文作者Eternal_Battle
本文链接https://www.cnblogs.com/Eternal-Battle/p/16040405.html
关于博主:这个世界除了你,都知道我喜欢你
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Gnomeshgh_k  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示