2022 5.10模拟

这篇博客记录了作者在编程竞赛中遇到的两个问题及其解决过程。第一题是关于动态规划的数组开小导致的错误,通过调整数组大小并优化DP状态转移解决了问题。第二题初始使用DFS求解,后来发现需要求最短路径,因此改用堆优化的Dijkstra算法,由于忽视了数据范围导致超时,最后调整数组大小通过了测试。
摘要由CSDN通过智能技术生成

前两道题很顺利,没什么可说的

从第三题,一次没过是因为数组开小了/(ㄒoㄒ)/~~,没看到k的范围。一开始数组只开到5000,但实际上要根据p和k的范围来DP。

一道很水的DP,随便推推就出来了。

#include<bits/stdc++.h>
#define re register
#define rep(a,b,c) for(re int a(b) ; a<=c ; ++a)
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48) ; ch=getchar();}
	return x*f;
}
inline void print(int x){
	if(x/10) print(x/10);
	putchar(x%10+'0');
}
const int M = 500010;
int n;
struct node{
	int l,r;
	friend bool operator < (node a,node b) {return a.r < b.r;}
}a[M];
int f[M];
int ans,maxn;
signed main(){
	freopen("hall.in","r",stdin);
	freopen("hall.out","w",stdout);
	n=read();
	rep(i,1,n) scanf("%d%d",&a[i].l,&a[i].r),maxn = max(maxn,a[i].r);
	sort(a+1,a+n+1);
	rep(i,1,n){
		int pos = a[i].r;
		f[pos] = a[i].r-a[i].l;
		rep(j,1,a[i].l) f[pos] = max(f[pos],f[j]+a[i].r-a[i].l);
	}
	rep(i,1,maxn) ans = max(ans,f[i]);
	printf("%d\n",ans);
	return 0;
}

 第四题。。就比较玄学。

先来看一下毒瘤的数据范围。

第一次没过,是因为我想简单了,直接一个dfs求出每一个点到起始点的距离,在树上写了个dfs,但错了一次后发现,实际上要求的是最短距离而不是dfs树上距离,于是就改成了用dij求最短路。 

可以发现。。根本没有给出p的范围(于是我就默认是n的范围做了),但。。两次提交都是TLE,我写的还是堆优化的dij,所以说,第一反应就是数组开销了。。实际上p的范围是小于等于1e6。。。。所以改完数组大小也就过了。

#include<bits/stdc++.h>
#define re register
#define int long long
#define rep(a,b,c) for(re int a(b) ; a<=c ; ++a)
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48) ; ch=getchar();}
	return x*f;
}
inline void print(int x){
	if(x/10) print(x/10);
	putchar(x%10+'0');
}
const int M = 2e6+10;
typedef pair<int,int> pii;
int n,p,c,m;
int dis[M],vis[M],head[M];
int cnt,ans;
struct edge{
	int to,nxt;
}e[M];
inline void add(int u,int v){
	e[++cnt].to = v;
	e[cnt].nxt = head[u];
	head[u] = cnt;
}
inline void dij(){
	priority_queue<pii,vector<pii>,greater<pii> >q;
	memset(dis,0x7f,sizeof(dis));
	dis[c] = 1;
	q.push(make_pair(1,c));
	while(!q.empty()){
		int u=q.top().second;
		q.pop();
		if(vis[u]) continue;
		vis[u] = 1;
		for(re int i(head[u]) ; i ; i=e[i].nxt){
			int v = e[i].to;
			if(dis[v] > dis[u]+1){
				dis[v] = dis[u]+1;
				if(!vis[v]) q.push(make_pair(dis[v],v));
			}
		}
	}
}
signed main(){
	freopen("candy.in","r",stdin);
	freopen("candy.out","w",stdout);
	n=read(),p=read(),c=read(),m=read();
	rep(i,1,p){
		int u=read(),v=read();
		add(u,v);
		add(v,u);
	}
	dij();
	rep(i,1,n) ans = max(ans,dis[i]+m);
	printf("%lld\n",ans);
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值