题意:

给出以最多6层的积木,每层可以由三个木块拼成,总共有三种颜色的木块,开始时给出了积木的排列情况,我们每次可以从积木中抽一块木块,抽木块的规则是投骰子,骰子分别投到red,blue,green,的概率为1/6,1/3,1/3.每次投骰子都要花费一分钟,如果投到的颜色不存在就等一分钟不操作。注意的是要保证不能从顶部抽,并且抽木块时不能让整个积木倒了,要保证不倒中间的木块必须存在,每次抽出的木块放到木块的顶部。现在要求到不能抽木块位置的时间期望。

题解:

这题要用状态压把整个积木的状态保存下来,但是很明显数组是存不了的,ll大小的状态量,那么我们考虑用hash来存,并且hash连同把dp的值也存进去。因为这题情况很多递推真心没法写啊,只能用记忆优化,搜索比较好操作点(算了,但我没说,搜索也很难写),用hash存状态的方法我只在插头dp中见到,这题真棒!在自己电脑上跑了7秒,在cf上竟然神一般1.9s。

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define B(x) (1<<(x))
typedef unsigned long long ll;
const int oo=0x3f3f3f3f;
const int SIZE=4000050;
const int P=67;
const int maxn=20;
int a[maxn],b[maxn];
int F[260];
char str[10];struct HASH{int head[SIZE],next[SIZE];ll state[SIZE];double dp[SIZE];int tol;void init(){memset(head,-1,sizeof head);tol=0;}double find(ll s){for(int i=head[s%SIZE];i!=-1;i=next[i]){if(state[i]==s) return dp[i];}return -1;}bool ins(ll s,double f){if(find(s)>-1)return false;dp[++tol]=f;state[tol]=s;next[tol]=head[s%SIZE];head[s%SIZE]=tol;return true;}
}mat;ll Hash(int n){for(int i=1;i<=n;i++)b[i]=a[i];sort(b+1,b+n);ll s=0;for(int i=1;i<=n;i++){s*=P;s+=b[i];}return s;
}inline void set_ST(int st[],int x){st[0]=(x>>4)&3;st[1]=(x>>2)&3;st[2]=x&3;
}inline int get_ST(int a,int b,int c){if(a>c)swap(a,c);//小优化return (((a<<2)+b)<<2)+c;
}double dfs(int n){ll s=Hash(n);double f=mat.find(s),c[4]={0,1e9,1e9,1e9};if(f>-1) return f;for(int i=1;i<n;i++){int x[3],y[3],nn=n;int ai=a[i],an=a[n];set_ST(x,ai);set_ST(y,an);if((!!x[0])+(!!x[1])+(!!x[2])==1)continue;if(y[0]&&y[1]&&y[2]){nn++;y[0]=y[1]=y[2]=0;}for(int j=0;j<3;j++)if(x[j]){if((!!x[0])+(!!x[1])+(!!x[2])==2&&(j==1||!x[1]))continue;int t=x[j];x[j]=0;a[i]=get_ST(x[0],x[1],x[2]);if((!!x[0])+(!!x[1])+(!!x[2])==1||!x[1])a[i]=0;///强力剪枝x[j]=t;for(int k=0;k<3;k++)if(!y[k]){y[k]=t;a[nn]=get_ST(y[0],y[1],y[2]);y[k]=0;c[t]=min(c[t],dfs(nn));}}a[i]=ai;a[n]=an;}if(c[1]==1e9&&c[2]==1e9&&c[3]==1e9){ mat.ins(s,0); return 0.0; }double p=1.0/6.0;if(c[1]==1e9) p+=1.0/3.0,c[1]=0;if(c[2]==1e9) p+=1.0/3.0,c[2]=0;if(c[3]==1e9) p+=1.0/6.0,c[3]=0;f=(c[1]/3.0+c[2]/3.0+c[3]/6.0+1.0)/(1.0-p);mat.ins(s,f);return f;
}int main(){int n;F['G']=1;F['B']=2;F['R']=3;mat.init();while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++){scanf("%s",str);a[i]=get_ST(F[str[0]],F[str[1]],F[str[2]]);}printf("%.15lf\n",dfs(n));}
}
/**
6
RGB
GRG
BBB
GGR
BRG
BRB
5
RGB
GRG
BBB
GGR
BRG
*/

codeforces 424E Colored Jenga (状态压缩,概率dp用hash记忆优化搜索)相关推荐

  1. ZOJ 3502 Contest 状态压缩 概率 DP

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3502 1 #include <iostream> 2 # ...

  2. Codeforces 678E. Another Sith Tournament(概率DP,状压)

    Codeforces 678E. Another Sith Tournament 题意: n(n<=18)个人打擂台赛,给定任意两人对决的胜负概率,比赛规则:可指定一人作为最开始的擂主,每次可指 ...

  3. HDU 1693(状态压缩 插头DP)

    我们引用国家队2008年陈丹琦的大作--<基于连通性状态压缩的动态规划问题>,上面对于插头.轮廓线的概念有详细的解释,不再赘述. 我们使用一个三维数组,前两维表示所在的格子,后一维表示轮廓 ...

  4. 洛谷 P-4045 密码(AC自动机+状态压缩+数位DP+乱搞)

    洛谷 P-4045 密码 记AC的第一道黑题! 题意:已知一段密码包含了一些字符串,然后求满足条件的密码有多少个,数量小于42时还得全部输出 思路: 一开始WA了两个点,不知道WA的什么,索性把读入的 ...

  5. TYVJ 2054 [Nescafé29]四叶草魔杖 最小生成树 状态压缩/背包DP

    $ \rightarrow $ 戳我进TYVJ原题 [Nescafé29]四叶草魔杖 题目限制 时间限制 内存限制 评测方式 题目来源 1000ms 131072KiB 标准比较器 Local 题目背 ...

  6. Codeforces 1293 E. Xenon‘s Attack on the Gangs —— 树上记忆化搜索,单点加改成区间加,有丶东西

    This way 题意: 现在有一棵大小为n的树,你要往边上放0~n-2这n-1个数,定义mex(u,v)表示u到v路径上的第一个未出现的自然数,定义S 问你S最大是多少. 题解: 我感觉这道题绝不止 ...

  7. 【DP】【记忆化搜索】NIKOLA(jzoj 1150)

    NIKOLA 题目大意: NIKOLA画了一排数字,他一开始在1,他可以往前跳T+1格(T为上一次跳到此格跳的格数),或往后T格(T一开始为0),但不能跳出界,没跳到一个格子,就要加上此格子的值(一开 ...

  8. CodeForces 1139D Steps to One(概率dp 容斥/莫比乌斯反演)

    题目链接https://codeforces.com/contest/1139/problem/D 题意:给定一个m,每次在1-m中随机取一个数放到容器中,当容器的gcd为1时停止,求期望步数,用分数 ...

  9. Codeforces 167B Wizards and Huge Prize(概率dp)

    题意: n个人,开始有一个容量为k得背包,击败一个人背包可以获得一定容量或得到一个财富(放入背包内),给出击败每个人的概率,求至少击败l个人,且背包容量大于获得的总财富值的概率 分析: 状态好确定,d ...

最新文章

  1. java maven项目使用sonar审核代码
  2. [翻译]一步步教你配置SQL SERVER合并复制(四)提高Distributor的安全性
  3. python将字典导入excel_python将字典列表导出为Excel文件的方法
  4. [Verilog] parameter
  5. Flask - app的配置和实例化Flask的参数
  6. 腾讯计费:亿万级大促活动自动化保障体系
  7. 【luogu】 P1880 石子合并
  8. python基础(part3)--运算符
  9. Java DB中的Java用户定义类型(UDT)
  10. 方便快捷的php长文章分页函数,PHP长文章分页的一种实现方法
  11. 罗技G304鼠标的按键宏定义
  12. iPhoneamp;iPad DFU及恢复模式刷机、降级教程
  13. 大数据从入门到实战——MongoDB实验——数据库基本操作
  14. 鲲鹏devkit(迁移 测试 性能分析) boostkit
  15. Terracotta 3.2.1简介 (二)
  16. 拉格朗日多项式插值法 思路详解+详细代码
  17. 按键精灵sub子程序篇
  18. 如何解决在打开pip时遇到Fatal error in launcher: Unable to create process using 的问题
  19. linux下的tar压缩解压缩命令详解,Linux下的tar压缩解压缩命令详解
  20. T1042/T2080 u-boot移植(一)

热门文章

  1. 使用极光推送详细步骤
  2. IDEA翻译插件Translate翻译失败报TKK: 更新 TKK 失败,请检查网络连接(已完结)
  3. 自己动手做一个虚拟魔方——建模、还原、可视化
  4. node.js+uni计算机毕设项目基于微信小程序的网上购物系统(程序+小程序+LW)
  5. matlab 正射影像,正射影像(DOM)的制作
  6. 使用腾讯官方的tbs调试微信中网页和小程序内容
  7. Java 将Excel文件转成PDF格式
  8. 【翻译】Batch Normalization: Accelerating Deep Network Trainingby Reducing Internal Covariate Shift
  9. floyd最短路算法的matlab程序,图论之最短路01——最短路矩阵(FLOYD)算法
  10. excel的相对引用和绝对引用