gym102220 Mini-game Before Contest

博主分享了在Codeforces Gym中遇到的F题解法,通过动态规划和深度优先搜索策略,描述了如何从无度节点出发判断比赛结果。文章强调了认真思考和避免比赛后期摸鱼的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://codeforces.com/gym/102220/problem/F

在vj跟着现场榜打的,没人开这题,水题啊卧槽,一直在想A题,A题难得一比卧槽,省赛还是要多开题,cf上gym牛逼网友F过了一车。虽然我当时看了这题但是因为没人过所以没有花很多时间想,晚上仔细想想一写就过了

用-1表示平局,0表示A获胜,1表示B获胜,b[i]=0/1表示他实际是希望谁赢的,dp[i][j]表示到了第i个点现在是第j个人移动时的状态

从没有出度的点开始,此时dp[i][1-6]是谁获胜了都知道了,就是当前移动的输了,接着吧他们放到队列里,队列里存新增的被确定为0或者1的dp[u][i],从队列里拿出一个u,i,然后枚举所有连向u的点v,及存在v->u的一条正向边,v可以走到u,如果dp[u][i]正如pre(i)所愿,dp[u][i]=b[pre(i)],那么直接把dp[v][pre(i)]确定,加进队列,否则如果与pre(i)期望相反,那么我们知道如果v能走到的所有点都与pre(i)期望相反,那么dp[v][pre(i)]才是必输的,否则他可以选择走某一个点得到平局,用一个du[v][pre(i)]来记录一下是不是全都必输了就行。

我们发现每一个dp[u][i]不等于-1也就是有确定的胜负之后,只会被加入队列一次,而且更新也只会更新一次,所以虽然是类似spfa的写法,但实际上只有O((n+m)*6)的复杂度

我好菜啊.jpg,以后一定要每道题都认真想想,不能比赛后期看没人过就摸鱼啊

#include<bits/stdc++.h>
using namespace std;

const int maxl=2e5+10;

int n,m;
int a[10],b[10];
int dp[maxl][7],du[maxl][7];
char ord[10],s[10];
typedef pair<int,int> p;
vector<int> e[maxl],fe[maxl];
queue<p> q;
bool in[maxl][7];

inline void prework()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=6;j++)
			dp[i][j]=-1,du[i][j]=0,in[i][j]=false;
		e[i].clear();
		fe[i].clear();
	}
	int u,v;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		fe[v].push_back(u);
		for(int j=1;j<=6;j++)
			du[u][j]++;
	}
	scanf("%s",ord+1);
	scanf("%s",s+1);
	for(int i=1;i<=6;i++)
		a[i]=s[i]-'0',b[i]=(ord[i]-'A')^a[i];
}

inline int pre(int i)
{
	if(i==1)
		return 6;
	return i-1;
}
inline int nxt(int i)
{
	if(i==6)
		return 1;
	return i+1;
}

inline void mainwork()
{
	while(!q.empty()) q.pop();
	for(int i=1;i<=n;i++)
	if(du[i][1]==0)
	{
		for(int j=1;j<=6;j++)
		if(ord[j]=='A')
		{	
			dp[i][j]=1; //A can't move B win
			q.push({i,j});in[i][j]=true;
		}
		else 
		{
			dp[i][j]=0;//0 -> A win
			q.push({i,j});in[i][j]=true;
		}
	}
	int u,i;p d;
	while(!q.empty())
	{
		d=q.front();q.pop();
		u=d.first;i=d.second;
		for(int v:fe[u])
		if(dp[v][pre(i)]==-1)
		{
			if(dp[u][i]==b[pre(i)])
			{
				dp[v][pre(i)]=b[pre(i)];
				q.push({v,pre(i)});in[v][pre(i)]=true;
			}
			else
			{
				du[v][pre(i)]--;
				if(du[v][pre(i)]==0)
				{
					dp[v][pre(i)]=b[pre(i)]^1;
					q.push({v,pre(i)});in[v][pre(i)]=true;
				}
			}
		}
	}
}

inline void print()
{
	for(int i=1;i<=n;i++)
	if(dp[i][1]<0)
		putchar('D');
	else 
		putchar('A'+dp[i][1]);
	puts("");
}

int main()
{
	int t;
	scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

### 使用PPO算法在gym-super-mario-bros环境中的实现 为了在 `gym-super-mario-bros` 游戏环境中应用近端策略优化 (Proximal Policy Optimization, PPO),可以按照以下方法构建模型并训练代理。以下是详细的说明: #### 安装依赖库 首先,确保安装必要的 Python 库来支持 `gym-super-mario-bros` 和强化学习框架 Stable Baselines3。 ```bash pip install nes-py gym-super-mario-bros stable-baselines3[extra] ``` 上述命令会安装 `nes-py`, `gym-super-mario-bros` 以及用于实现 PPO 的强化学习工具包 `Stable-Baselines3`[^1]。 --- #### 创建超级马里奥环境 通过导入 `SuperMarioBros-v0` 或其他变体创建游戏环境,并设置动作空间和观察空间。 ```python import gym_super_mario_bros from nes_py.wrappers import JoypadSpace from gym.spaces import Box from gym.wrappers import FrameStack from stable_baselines3.common.env_checker import check_env from stable_baselines3 import PPO # 初始化 Super Mario Bros 环境 env = gym_super_mario_bros.make('SuperMarioBros-v0') # 设置简化操作集 env = JoypadSpace(env, [['right'], ['right', 'A']]) # 将帧堆叠到一起以提供时间序列数据给神经网络 env = FrameStack(env, num_stack=4) # 验证环境是否兼容稳定基线的要求 check_env(env) ``` 此部分代码定义了一个简单的控制方案(右移或跳跃),并通过 `FrameStack` 提供连续四帧作为输入状态。 --- #### 训练PPO模型 使用 `stable-baselines3.PPO` 来初始化和训练代理。 ```python model = PPO( policy="CnnPolicy", env=env, verbose=1, tensorboard_log="./mario_ppo_tensorboard/" ) # 开始训练过程 model.learn(total_timesteps=int(1e6)) # 保存训练好的模型 model.save("ppo_mario") ``` 在此配置中: - **policy**: 使用卷积神经网络 (`CnnPolicy`) 处理图像型观测值。 - **total_timesteps**: 总共执行 $1 \times 10^6$ 时间步数进行训练。 - **tensorboard_log**: 可视化日志路径以便监控训练进展。 --- #### 测试已训练的模型 加载先前保存的模型并对环境运行推理测试。 ```python del model # 删除旧模型以防冲突 # 加载预训练模型 model = PPO.load("ppo_mario") state = env.reset() done = False while not done: action, _states = model.predict(state) state, reward, done, info = env.step(action) env.render() env.close() ``` 这段脚本展示了如何利用训练完成后的模型在游戏中做出决策。 --- ### 注意事项 1. 超参数调整对于性能至关重要。例如,更改学习率、批量大小或其他超参数可能显著影响收敛速度与最终效果。 2. 如果希望扩展功能,可考虑引入更复杂的奖励机制或者自定义环境封装器。 3. 对于更高难度级别(如世界 1-2 或以上),建议增加训练时间和样本数量。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值