链接:http://118.190.20.162/view.page?gpid=T132


思路:先写一个暴力搜索,然后把中间结点的状态存起来,就是记忆化搜索,状态要存搜索到的层数和选择的卡牌数,0代表不选,1代表选,可以把16个卡牌是否选的状态压缩到2的16次方的一个int数中。
注意:1.题目有一个坑点,题目里的精度是骗人的,输出精度要达到1e-10才行,1e-5的精度会WA
2.dp数组第一维度保存层数,极端情况是是16张牌,一张牌概率0.9985,其他牌概率0.0001,k最大=5,所以树的深度最深是75左右,所以开100就够,存01状压的维度,要大于2的16次方也就是65536,所以可以开70000
3.考场上脑抽了,更新了dp数组后,没有用dp数组已经保存的值,而是又dfs下去了。。然后超时
先上20分的暴力搜索代码

2022/5/9更新:
好多人私信我问我代码的问题,我先讲一下暴力递归的分析思路:
先是想一颗树,第一层是N张牌,对于第一层的每张牌,第二层再抽N张牌,以此类推,对这颗树进行搜索的时候,就是进行一次深搜,我最终的期望相当于第一层每个结点期望的加权求和,那就是抽到每张牌的概率p乘上这个结点的期望值。之后的层同理。但是发现搜索空间太大,必须记忆化,这是dp类题目。
做dp类题目先想状态的表示,这个题根据数据可以知道要用状态压缩dp,即0和1代表卡牌的有无,但是只用一维不能解决问题,当时我是先写出了暴力的代码,根据函数的参数发现层数也需要存一下,相当于一共参与了几次抽卡。
然后发现状态转移和暴力的一样,于是改动不大,只需要把状态存起来就好。

#include <bits/stdc++.h>
const int maxn=50;
using namespace std;
double p[maxn+5];
int book[maxn+5];
int N,K;
double dfs(int now,int lev,int left){if((lev-(N-left))/K>=left)return lev;int flag=1;for(int i=0;i<N;i++){if(book[i]==0)flag=0;}if(flag==1)return lev;double ans=0;for(int i=0;i<N;i++){if(book[i]==0){book[i]=1;ans+=p[i]*dfs(i,lev+1,left-1);book[i]=0;}else ans+=p[i]*dfs(i,lev+1,left);}return ans;
}
int main()
{cin>>N>>K;for(int i=0;i<N;i++){cin>>p[i];}double ans=0;for(int i=0;i<N;i++){book[i]=1;ans+=p[i]*dfs(i,1,N-1);book[i]=0;}cout<<ans<<endl;return 0;
}

然后是满分的状压+记忆化搜索代码

#include <bits/stdc++.h>
const int maxn=50;
using namespace std;
double p[maxn+5];
int book[maxn+5];
int N,K;
double dp[1000][70000];
double dfs(int lev,int left,int state){//层数,剩余牌数,01选或者不选的状态if((lev-(N-left))/K>=left)return lev;double ans=0;for(int i=0;i<N;i++){int temps;if(book[i]==0){book[i]=1;temps=state|(1<<i);if(dp[lev+1][temps]==0){dp[lev+1][temps]=dfs(lev+1,left-1,temps);}ans+=p[i]*dp[lev+1][temps];book[i]=0;}else{if(dp[lev+1][state]==0){dp[lev+1][state]=dfs(lev+1,left,state);}ans+=p[i]*dp[lev+1][state];}}return ans;
}
int main()
{cin>>N>>K;for(int i=0;i<N;i++){cin>>p[i];}double ans=0;for(int i=0;i<N;i++){book[i]=1;int st=(1<<i);if(dp[1][st]==0){dp[1][st]=dfs(1,N-1,st);}ans+=p[i]*dfs(1,N-1,st);book[i]=0;}printf("%.10f",ans);return 0;
}

考完以后写了一个更短的。。

#include <iostream>
const int maxn=30;
using namespace std;
int N,K;
double p[maxn+5];
int book[maxn+5];
double dp[100][80000];
double dfs(int level,int have,int state){//层数,已经抽中的卡牌数,01状态if((N-have)*K<=level-have){return level;}double ans=0;for(int i=0;i<N;i++){if(book[i]==0){book[i]=1;if(dp[level+1][state+(1<<i)]==0){dp[level+1][state+(1<<i)]=dfs(level+1,have+1,state+(1<<i));}ans+=p[i]*dp[level+1][state+(1<<i)];book[i]=0;}else{if(dp[level+1][state]==0){dp[level+1][state]=dfs(level+1,have,state);}ans+=p[i]*dp[level+1][state];}}return ans;
}
int main()
{cin>>N>>K;for(int i=0;i<N;i++){cin>>p[i];}double ans=dfs(0,0,0);printf("%.10f",ans);return 0;
}

第23次CSP认证 第4题 收集卡牌(记忆化搜索,状压)相关推荐

  1. 第23次CSP认证(202109)

    第23次CSP认证---202109 第一题 :数组推导    (贪心) 第二题 :非零段划分   (差分) 第三题 :脉冲神经网络(模拟) 第四题 :收集卡牌( DP ) 第一题 :数组推导    ...

  2. 巧用记忆化搜索代替暴力递归(洛谷P1464题题解,Java语言描述)

    题目要求 P1464题目链接 分析 如果--你信了这题干,真的写了递归--TLE警告!!! 所以,就需要优化嘛-- [−9223372036854775808,9223372036854775807] ...

  3. python认证考试_Python入门习题(39)——CCF CSP认证考试真题:公共钥匙盒

    CCF CSP认证考试真题:共钥匙盒 问题描述 试题编号:201709-2 试题名称:公共钥匙盒 时间限制:1.0s 内存限制:256.0MB 问题描述 有一个学校的老师共用N个教室,按照规定,所有的 ...

  4. 2017广东工业大学程序设计竞赛决赛 题解源码(A,数学解方程,B,贪心博弈,C,递归,D,水,E,贪心,面试题,F,贪心,枚举,LCA,G,dp,记忆化搜索,H,思维题)...

    心得: 这比赛真的是不要不要的,pending了一下午,也不知道对错,直接做过去就是了,也没有管太多! Problem A: 两只老虎 Description 来,我们先来放松下,听听儿歌,一起&qu ...

  5. 【蓝桥杯真题】地宫取宝(搜索-记忆化搜索详解)

    链接 [蓝桥杯][2014年第五届真题]地宫取宝 题目描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被 ...

  6. 22.11.30打卡 记忆化搜索2水题

    Function Run Fun 记忆化搜索模板题, 个人认为比滑雪还简单 需要注意的只有当数组下标为负数的时候需要特判一下 其余直接照抄题目就能过了 /* ⣿⣿⣿⣿⣿⣿⡷⣯⢿⣿⣷⣻⢯⣿⡽⣻⢿⣿⣿⣿⣿ ...

  7. CSP认证题解第一题

    文章目录 202012-1 期末预测之安全指数 202009-1 称检测点查询 202006-1 线性分类器 201912-1 报数 201909-1 小明种苹果 201903-1 小中大 20181 ...

  8. CCF CSP认证历年真题 满分代码(持续更新中)

    目标 在接下来的半年到一年时间内,补全CCF认证历年真题(A-D)的满分代码(E题随缘). 考虑到CCF认证这个东西是可以混分的,我计划对D.E题额外增加部分分代码,或许有助于不同层次的选手备赛. 除 ...

  9. CCF CSP认证菜鸟刷题日志

    CCF CSP菜鸟刷题日志(c/c++) 本萌新写给自己看的,要是有大佬路过,请多多指教orz 立个flag:每日一更,至201903 9月15ccf csp,冲鸭! 今天(2019.8.18)起每天 ...

最新文章

  1. cmd编译java命令_使用CMD命令编译执行java命令
  2. Week8 Teamework from Z.XML-Z.XML游戏功能说明
  3. 寒冬悟道者马云:阿里巴巴逢单出击(4)
  4. Spring Boot结合spring-data-jpa
  5. pythonweb框架使用教程_Django视频教程 - 基于Python的Web框架(全13集)
  6. Leetcode PHP题解--D56 637. Average of Levels in Binary Tree
  7. 6.边缘检测:梯度——边缘检测、导数与边缘、什么是梯度_2
  8. 个盘子的汉诺塔需要移动几步_坨——理解递归实现quot;汉诺塔quot;代码的关键...
  9. 软件测试学习视频教程-精通软件测试教程
  10. java创建环境变量是用户还是系统_5.Java环境变量配置
  11. java入门到精通第六版_java从入门到精通-第6章.pdf
  12. java 汽车类_汽车类 - java代码库 - 云代码
  13. 点击自定义按钮弹出百度商桥对话框
  14. 蓝牙耳机一个响一个不响怎么办
  15. Mac版Sublime Text3搭建c语言环境
  16. 电脑程序是如何运行起来的
  17. 基于安卓的备忘录文件加密_苹果备忘录、锤子便签、印象笔记哪个更好用?
  18. 使用Bboss处理ES的dsl语句
  19. leetcode-数据结构-566. 重塑矩阵
  20. robotframework以手机模式打开浏览器

热门文章

  1. 华为nova5pro能换鸿蒙系统吗,华为nova7se可以升级鸿蒙系统吗
  2. RLE算法机制、缺点及哈夫曼算法和莫尔斯编码
  3. java十次方社交项目实战(完整)
  4. SR锁存器——数电第五章学习
  5. STM32+ov7725图像识别(HSL原理)
  6. 高考399分的深圳流水线女工 逆袭成谷歌高薪程序员
  7. 世界中を敵にしても君を守る
  8. android activity生命周期(一)onCreate和onDestroy方法
  9. Redis实现分页查询
  10. Linux安装tigase7.1