2018-2019 ACM-ICPC Nordic Collegiate Programming Contest E题 Explosion Exploit (状压+记忆化dfs)

题目链接:https://codeforc.es/gym/101933/problem/E

题意:玩家和敌手进行游戏,玩家有n枚棋子,敌手有m枚棋子,每枚棋子剩余血量均给出,现一共出现d次攻击,从所有棋子中随机挑选一个攻击,攻击值为1,若棋子血量为0则消失,问敌手全部棋子均消失的概率

思路:题目数据量很小,可以dfs,但是如果直接暴力搜会t,需要记忆化,但是要把所有状态存下来,如果开一个11维的数组空间上没办法,看了别人的思路之后发现,可以巧妙的压缩这些状态,用一个15位的整数st表示当前状态,从高位到低位的含义:

第1~3位表示当前剩余攻击次数,第4~9位分别表示敌方1~6滴血的棋子数,第10~15位表示玩家1~6滴血的棋子数,可见当该整数减去高位的攻击次数后若小于1e7则敌方所有棋子均已消失

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;

typedef long long ll;
int p[2][7];
int n, m, d;
ll c[20];
map<ll, double> mm;

double dfs(ll sta, int t)
{
	if (mm.count(sta))return mm[sta];
	if (sta  - t*c[13] < c[7])return 1.0; 
	if (t <= 0)return 0;

	int res = n + m - p[0][0] - p[1][0];
	double ans = 0;
	for (int i = 0; i < 2; i++)
	{
		for (int j = 6; j > 0; j--)
		{
			if (p[i][j])
			{
				p[i][j]--, p[i][j - 1]++;
				double tmp;
				ll stan;
				if(j==1)
					stan = sta - c[i * 6 + j] - c[13];
				else
					stan = sta - c[i * 6 + j] + c[i * 6 + j - 1] - c[13];
				tmp = dfs(stan, t - 1);
				mm[stan] = tmp;
				p[i][j]++, p[i][j - 1]--;
				ans += tmp * p[i][j] / (1.0*res);
			}
		}
	}
	return ans;
}

int main()
{
	scanf("%d%d%d", &n, &m, &d);
	memset(p, 0, sizeof(p));
	int a = 0, b = 0;
	c[1] = 1;
	for (int i = 2; i < 15; i++)
		c[i] = c[i - 1] * 10;
	ll stanow = d * c[13];
	for (int i = 0; i < n; i++)
	{
		int k;
		scanf("%d", &k);
		a += k;
		p[0][k]++;
		stanow += c[k];
	}
	for (int i = 0; i < m; i++)
	{
		int k;
		scanf("%d", &k);
		a += k;
		b += k;
		p[1][k]++;
		stanow += c[6+k];
	}
	if (a <= d)
	{
		printf("1\n");
	}
	else if (b > d)
	{
		printf("0\n");
	}
	else
	{
		double ans = dfs(stanow, d);
		printf("%.8lf\n", ans);
	}
}

 

### 配置 PyCharm 使用 Anaconda 环境并更镜像源 #### 更改 Conda 的默认通道至国内镜像源 为了提高下载速度和稳定性,在配置 PyCharm 使用 Anaconda 环境之前,可以先更改 conda 默认使用的软件仓库到清华大学开源软件镜像站。这一步骤通过命令行完成: ```bash conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ ``` 此操作会向 `channels` 列表中添加清华的 conda-forge 渠道[^2]。 #### 创建新的 Conda 虚拟环境 接着创建一个新的 Conda 虚拟环境,并确保其中已安装 Jupyter Notebook 所需组件如 `ipykernel`: ```bash conda create -n myenv python=3.x ipykernel jupyterlab ``` 这里的 `-n myenv` 表示新环境的名字为 "myenv";而 `python=3.x` 应替为你想要的具体 Python 版本号[^1]。 #### 将新环境注册给 Jupyter Kernel 为了让 Jupyter 可识别刚建立好的 Conda 环境作为 kernel 选项之一,执行如下指令来使当前激活的新环境中包含有可用内核: ```bash python -m ipykernel install --user --name=myenv --display-name "Python (myenv)" ``` 这条语句的作用是在全局范围内将名为 “myenv” 的 Conda 环境加入到了 Jupyter notebook/kernelspecs 下面,使得可以在启动后的 Jupyter 中看到这个自定义名称对应的解释器。 #### 在 PyCharm 中配置 Anaconda 解释器 打开 PyCharm 后进入 **File -> Settings** (对于 macOS 用户则是 **PyCharm -> Preferences**) ,导航到 **Project: project_name -> Python Interpreter** 。点击右上角齿轮图标选择 **Add...**, 接着挑选 **Conda Environment -> Existing environment** 并浏览找到刚才创建的那个 Conda 环境路径下的 Python.exe 文件位置(通常位于 anaconda3/envs/myenv/python.exe)。这样就完成了在 PyCharm 内部对特定 Conda 环境的选择与应用[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值