杭州学军中学信友队 趣味网络邀请赛题解

A. 核酸检测

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

#include<iostream>
#include<cstdio>
using namespace std;
void deal1(int n){
	int t1,t2;
	for(int i=n;i>1;i-=2)
	{
		t1=i,t2=i-1;
		for(int j=1;j<=n+1;j++)
		{
			printf("%d %d\n",t1,j);
			swap(t1,t2);
		}
		for(int j=n+1;j>0;j--)
		{
			printf("%d %d\n",t1,j);
			swap(t1,t2);
		}
	}
	for(int i=1;i<=n+1;i++)
		printf("1 %d\n",i);
}
void deal2(int n){
	int t1,t2;
	for(int i=n+1;i>1;i-=2)
	{
		t1=i,t2=i-1;
		for(int j=n;j>0;j--)
		{
			printf("%d %d\n",j,t1);
			swap(t1,t2);
		}
		for(int j=1;j<n+1;j++)
		{
			printf("%d %d\n",j,t1);
			swap(t1,t2);
		}
	}
	for(int i=n;i>0;i--)
		printf("%d 1\n",i);
}
int main(){
	int n;
	scanf("%d",&n);
	printf("%d\n",n*(n+1)-1);
	if(n%2)
		deal1(n);
	else
		deal2(n);
	return 0;
} 

B. 齐心抗疫

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 50010
typedef struct node{
	int head;
	int v;
}Node;
typedef struct point{
	public:
	int v,len;
	point(int _v,int _len){
		v=_v;
		len=_len;
	}
}Point;
struct {
	int u,v;
	int len;
}mpath;

Node no[N];
int a[N],n,vi[N],head[N],cnt=1,va[N],ans=0;
void add(int u,int v){
	no[cnt].head=head[u];
	no[cnt].v=v;
	head[u]=cnt;
	cnt++;
}
Point dfs(int id){
	vi[id]=1;
	Point t1(id,0),t2(id,0);
	for(int i=head[id];i!=0;i=no[i].head)
	{
		if(vi[no[i].v]==0)
		{
			Point t=dfs(no[i].v);
			if(t.len>t2.len)
			{
				if(t.len>t1.len)
				{
					t2=t1;
					t1=t;
				}
				else
				{
					t2=t;
				}
			}
		}
	}
	if(t1.len+t2.len>mpath.len)
	{
		mpath.u=t1.v;
		mpath.v=t2.v;
		mpath.len=t1.len+t2.len;
	}
	t1.len++;
	return t1;
}
void initial(){
	mpath.len=0;
	memset(vi,0,sizeof(vi));
	memset(head,0,sizeof(head));
}
void dfs2(int sta,int cur,int len,int *cost){
	vi[cur]=1;
	for(int i=head[cur];i!=0;i=no[i].head)
	{
		if(vi[no[i].v]==0)
		{
			cost[no[i].v]=max(a[no[i].v],a[sta])*len;
			ans=max(cost[no[i].v],ans);
			dfs2(sta,no[i].v,len+1,cost);
		}
	}
}
int main(){
	int u,v;
	initial();
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}	
	dfs(1);
	memset(vi,0,sizeof(vi));
	dfs2(mpath.u,mpath.u,1,va);
	memset(vi,0,sizeof(vi));
	dfs2(mpath.v,mpath.v,1,va);
	printf("%d",ans);
	return 0;
}

C. 病毒研究

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
#define N 2010
const ll inf=1e10;
int n,m,a[N],sp[N],sc[N];   //sp[i]=活性为i的状态值 - 1; //sc[i]=活性为i的状态值 
ll cost[N],f[N][2],sum[N];  //sum[i]表示状态i的区间内最少的期望值 
ll count(int li,int ri){
	if(ri<=a[1])
		return 0;
	int pl=sc[li],pr=sp[ri];
	if(pl>pr)
		return inf;
	ll value=sum[pr]-sum[pl];
	value+=f[li][1]; 
	value+=f[ri][0];
	return value;
}
ll dp(int li,int ri){ //进行状态转移计算 
	if(ri<a[1])
		return 0;
	ll value=inf;
	for(int i=1;i<li;i++)
	{
		value=min(value,count(li-i,ri-i)+(ri-li+1)*cost[i]);
	}
	return value;
}
int main(){
	int t,v,w;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		a[0]=0;
		for(int i=1,j=0;i<=n;i++)
		{
			scanf("%d",&a[i]);
			while(j<=a[i])
			{
				sp[j]=i-1,sc[j]=i;
				j++;
			}	
		}
		cost[0]=0;
		for(int i=0;i<=a[n];i++)
			cost[i]=inf;
		for(int i=0;i<m;i++)
		{
			scanf("%d%d",&v,&w);
			for(int i=1;i<=a[n];i++)
			{
				cost[i]=min(cost[i],cost[i-w]+v); //完全背包的计算,算出活性减为0的最小花费 
			}
		}
		for(int i=1;i<=a[n];i++)
		{
			//状态压缩动态规划 
			for(int j=a[i]+1;j<=a[i+1];j++)    
			{
				f[j][0]=dp(a[i]+1,j);
			}
			for(int j=a[i]+1;j<=a[i+1];j++)
			{
				f[j][1]=dp(j,a[i+1]);
			}
			sum[i]=sum[i-1]+f[a[i]][0];   //使用前缀和进行累加计算 
		}
		if(sum[n]>=inf)  //找不到最少期望 
			printf("-1");
		else
			printf("%lld\n",sum[n]);  //最少期望为每种状态区间的最小值的累加和 
	}
	return 0;
}

剩下的题不会做了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值