当前位置: 首页 > news >正文

NCPC 2018 Explosion Exploit

我方有 \(n\) 个小黄人,分别为 \(a_i\), 敌方有 \(m\) 个小黄人,分别为\(b_i\), 小黄人的健康值为 \([1,6]\) 中的整数 .

\(d\) 个炸弹,每次会有均匀的概率摧毁我方和敌方的任何活着的小黄人,此时这个被选中的小黄人健康值 --,如果健康值为0的话,小黄人就会死掉。

\(d\) 个炸弹之后,敌方小黄人全死光的概率是多少(我方小黄人是不是活着不重要)。

\(1\leq n,m\leq 5, 1\leq d\leq 100\)

简单的想法,用一共 \(n+m\) 个范围为 \(0\)\(6\) 的位置来表示当前每个小黄人的健康值,然后还需要一个维表示有多少个 bombs 剩下。

但这个时间复杂度肯定是爆炸的,此时观察到是否是敌方/我方小黄人是重要的,但是敌方 & 我方小黄人中每个位置上当前健康值是多少是不重要的。只需要知道我方/敌方当前有多少个小黄人健康值为 \(0,1,2,3,4,5,6\) 就好了。

此时就可以状态为 \((s_0, s_1, s_2,s_3,s_4,s_5,s_6)\) ,这个大概在不到 \(500\) 个.

这里需要注意是需要状压的,实际出现的可能组合远远小于 \(7^5\) .

假设当前状态为 \(f(i,s_0,s_1,s_2,s_3,s_4,s_5,s_6,t_0,t_1,t_2,t_3,t_4,t_5,t_6)\),

此时炸到健康值为 \(s_i, i>0\) 的概率是 \(\frac{s_i}{\sum{s_j}+\sum{t_j}-s_0-t_0}\),

只需要把 \(f(i,s_0,s_1,s_2,s_3,s_4,s_5,s_6,t_0,t_1,t_2,t_3,t_4,t_5,t_6) \times \frac{s_i}{\sum{s_j}+\sum{t_j}-s_0-t_0}\) 转移到新的 \(f(i-1,\cdots,s_{i-1}+1,s_i-1,\cdots,t_0,t_1,t_2,t_3,t_4,t_5,t_6)\) 就可以啦。

对于选择的是 \(t_i\) 的同理。

时间复杂度: \(O(500^2d)\)

空间复杂度: \(O(500^2d)\)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int D=505;
const double eps=1e-18;
int n,m,d;
int a[10],b[10],sta[D],stb[D],cnta[10],cntb[10],tota=0,totb=0;
map<int,int>ma,mb;
inline int calc(int s0,int s1,int s2,int s3,int s4,int s5,int s6){int mask=s6;mask=mask*6+s5;mask=mask*6+s4;mask=mask*6+s3;mask=mask*6+s2;mask=mask*6+s1;mask=mask*6+s0;return mask;
}
void dfsa(int s0,int s1,int s2,int s3,int s4,int s5,int s6,int tot){if(s0+s1+s2+s3+s4+s5+s6==tot){if(ma.find(calc(s0,s1,s2,s3,s4,s5,s6))==ma.end()){sta[tota]=calc(s0,s1,s2,s3,s4,s5,s6);ma[calc(s0,s1,s2,s3,s4,s5,s6)]=tota++;}return;}dfsa(s0+1,s1,s2,s3,s4,s5,s6,tot);dfsa(s0,s1+1,s2,s3,s4,s5,s6,tot);dfsa(s0,s1,s2+1,s3,s4,s5,s6,tot);dfsa(s0,s1,s2,s3+1,s4,s5,s6,tot);dfsa(s0,s1,s2,s3,s4+1,s5,s6,tot);dfsa(s0,s1,s2,s3,s4,s5+1,s6,tot);dfsa(s0,s1,s2,s3,s4,s5,s6+1,tot);
}
void dfsb(int s0,int s1,int s2,int s3,int s4,int s5,int s6,int tot){if(s0+s1+s2+s3+s4+s5+s6==tot){if(mb.find(calc(s0,s1,s2,s3,s4,s5,s6))==mb.end()){stb[totb]=calc(s0,s1,s2,s3,s4,s5,s6);mb[calc(s0,s1,s2,s3,s4,s5,s6)]=totb++;}return;}dfsb(s0+1,s1,s2,s3,s4,s5,s6,tot);dfsb(s0,s1+1,s2,s3,s4,s5,s6,tot);dfsb(s0,s1,s2+1,s3,s4,s5,s6,tot);dfsb(s0,s1,s2,s3+1,s4,s5,s6,tot);dfsb(s0,s1,s2,s3,s4+1,s5,s6,tot);dfsb(s0,s1,s2,s3,s4,s5+1,s6,tot);dfsb(s0,s1,s2,s3,s4,s5,s6+1,tot);
}
double f[D][D][D];
void solv(int lft,int ida,int idb){int maska=sta[ida],maskb=stb[idb];for(int i=0;i<=6;i++)cnta[i]=maska%6,maska/=6;for(int i=0;i<=6;i++)cntb[i]=maskb%6,maskb/=6;int ala=0,alb=0;for(int i=1;i<=6;i++)ala+=cnta[i];for(int i=1;i<=6;i++)alb+=cntb[i]; for(int i=1;i<=6;i++)if(cnta[i]){cnta[i]--;cnta[i-1]++;int nmska=calc(cnta[0],cnta[1],cnta[2],cnta[3],cnta[4],cnta[5],cnta[6]);int nida=ma[nmska];cnta[i]++;cnta[i-1]--;f[lft+1][nida][idb]+=f[lft][ida][idb]/(ala+alb)*cnta[i];}for(int i=1;i<=6;i++)if(cntb[i]){cntb[i]--;cntb[i-1]++;int nmskb=calc(cntb[0],cntb[1],cntb[2],cntb[3],cntb[4],cntb[5],cntb[6]);int nidb=mb[nmskb];cntb[i]++;cntb[i-1]--;f[lft+1][ida][nidb]+=f[lft][ida][idb]/(ala+alb)*cntb[i];}if(ala+alb==0){f[lft+1][ida][idb]+=f[lft][ida][idb];}
}
void get_ans(double&ans,int ida,int idb){int maska=sta[ida],maskb=stb[idb];for(int i=0;i<=6;i++)cnta[i]=maska%6,maska/=6;for(int i=0;i<=6;i++)cntb[i]=maskb%6,maskb/=6;if(cntb[0]==m)ans+=f[d][ida][idb];
}
int main(){cin>>n>>m>>d;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=m;i++)cin>>b[i];dfsa(0,0,0,0,0,0,0,n);dfsb(0,0,0,0,0,0,0,m);
//	cerr<<tota<<endl;
//	for(int i=0;i<tota;i++)cerr<<sta[i]<<" ";cerr<<endl;
//	cerr<<totb<<endl;
//	for(int i=0;i<totb;i++)cerr<<stb[i]<<" ";cerr<<endl; for(int i=1;i<=n;i++)cnta[a[i]]++;for(int i=1;i<=m;i++)cntb[b[i]]++;int omska=calc(cnta[0],cnta[1],cnta[2],cnta[3],cnta[4],cnta[5],cnta[6]);int omskb=calc(cntb[0],cntb[1],cntb[2],cntb[3],cntb[4],cntb[5],cntb[6]);f[0][ma[omska]][mb[omskb]]=1.0;for(int i=0;i<d;i++){for(int ida=0;ida<tota;ida++)for(int idb=0;idb<totb;idb++){if(f[i][ida][idb]<eps)continue;solv(i,ida,idb);}}double ans=0;for(int ida=0;ida<tota;ida++)for(int idb=0;idb<totb;idb++){get_ans(ans,ida,idb);}cout<<fixed<<setprecision(8)<<ans<<endl;return 0;
} 
/*
5 5 100
6 6 6 6 6
6 6 6 6 6 
*/
/*
1 1 12
6 
6
*/
http://www.jsqmd.com/news/324160/

相关文章:

  • 封边机升级改造哪家好?封边机规方连线哪家好?2026封边机多带道改造厂家+封边机连线解决方案厂商全攻略
  • 2026佛山非标自动化配套工厂甄选:六面钻连线定制厂家盘点附带濠派设备升级改造靠谱吗解析
  • 隔断镂空砖厂家/幕墙干挂陶板砖定制厂家需要具备哪些优势?2026厂家盘点分析
  • 【课程设计/毕业设计】基于SpringBoot+Vue的汽车租赁管理系统管理系统设计与实现基于MyBatis的在线车辆租赁信息管理系统的设计与实现【附源码、数据库、万字文档】
  • 2026年靠谱的装配式内装冰火板高分厂家推荐
  • 还在找专业屋面陶土瓦厂家/别墅陶瓷瓦厂家?2026厂家综合盘点
  • Java毕设选题推荐:基于springboot的游戏分享网站的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Java计算机毕设之基于springboot的游戏分享网站的设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • 智慧农业之辣椒检测目标检测数据集 农产品分拣场景识别 青甜椒与红甜椒自动识别 智能农业设备开发识别 深度学习YOLO格式10460期
  • 干挂陶土砖定制厂家/多孔陶土砖厂家怎么选?2026厂家使用好评汇总分析
  • 2026年靠谱的硅酸钙冰火板好评厂家曝光
  • 全自动凉皮机哪家好?专业的凉皮机哪家好?2026精选厂家汇总
  • Java毕设选题推荐:基于SpringBoot的电脑笔记本维修工单进度管理系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 键盘映射工具改键位,绿色版设置后重启生效
  • 圆盘凉皮机哪家好?2026厂家汇总从质量到标杆的品质之选盘点
  • Java计算机毕设之基于SpringBoot的电脑维修工单售后管理系统的设计与实现基于SpringBoot的电脑维修工单管理系统的设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • C# 关于联合编程基础
  • Java计算机毕设之基于MyBatis的在线车辆租赁信息管理系统的设计与实现基于 Spring Boot+MySQL 的汽车租赁管理系统设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • ONLYOFFICE AI 插件新功能:轻松创建专属 AI 助手
  • 酿皮机哪家好?米皮机哪家好?2026厂家盘点,以技术实力定义行业标杆
  • 取名软件:输入信息匹配名字智能打分无广告
  • 2026年比较好的乳胶用橡胶助剂/功能橡胶助剂热门厂家榜
  • “数字员工”的基本能力和特殊有哪些?
  • [嵌入式系统-166]:电机类型的演进过程
  • 构建学生健康午休生态,为教育装备现代化提质增效
  • 企业级政府管理系统管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】
  • 【Vue 功能总结】Element UI 级联组件实现
  • 前后端分离搭建疫情管理系统系统|SpringBoot+Vue+MyBatis+MySQL完整源码+部署教程
  • Windows 系统 Qt 下载、安装与环境配置全教程
  • 2月2日 – 2月7日直播:6天掌握Tilelang-Ascend开发