第23次CSP认证 第4题 收集卡牌(记忆化搜索,状压)
链接: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题 收集卡牌(记忆化搜索,状压)相关推荐
- 第23次CSP认证(202109)
第23次CSP认证---202109 第一题 :数组推导 (贪心) 第二题 :非零段划分 (差分) 第三题 :脉冲神经网络(模拟) 第四题 :收集卡牌( DP ) 第一题 :数组推导 ...
- 巧用记忆化搜索代替暴力递归(洛谷P1464题题解,Java语言描述)
题目要求 P1464题目链接 分析 如果--你信了这题干,真的写了递归--TLE警告!!! 所以,就需要优化嘛-- [−9223372036854775808,9223372036854775807] ...
- python认证考试_Python入门习题(39)——CCF CSP认证考试真题:公共钥匙盒
CCF CSP认证考试真题:共钥匙盒 问题描述 试题编号:201709-2 试题名称:公共钥匙盒 时间限制:1.0s 内存限制:256.0MB 问题描述 有一个学校的老师共用N个教室,按照规定,所有的 ...
- 2017广东工业大学程序设计竞赛决赛 题解源码(A,数学解方程,B,贪心博弈,C,递归,D,水,E,贪心,面试题,F,贪心,枚举,LCA,G,dp,记忆化搜索,H,思维题)...
心得: 这比赛真的是不要不要的,pending了一下午,也不知道对错,直接做过去就是了,也没有管太多! Problem A: 两只老虎 Description 来,我们先来放松下,听听儿歌,一起&qu ...
- 【蓝桥杯真题】地宫取宝(搜索-记忆化搜索详解)
链接 [蓝桥杯][2014年第五届真题]地宫取宝 题目描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被 ...
- 22.11.30打卡 记忆化搜索2水题
Function Run Fun 记忆化搜索模板题, 个人认为比滑雪还简单 需要注意的只有当数组下标为负数的时候需要特判一下 其余直接照抄题目就能过了 /* ⣿⣿⣿⣿⣿⣿⡷⣯⢿⣿⣷⣻⢯⣿⡽⣻⢿⣿⣿⣿⣿ ...
- CSP认证题解第一题
文章目录 202012-1 期末预测之安全指数 202009-1 称检测点查询 202006-1 线性分类器 201912-1 报数 201909-1 小明种苹果 201903-1 小中大 20181 ...
- CCF CSP认证历年真题 满分代码(持续更新中)
目标 在接下来的半年到一年时间内,补全CCF认证历年真题(A-D)的满分代码(E题随缘). 考虑到CCF认证这个东西是可以混分的,我计划对D.E题额外增加部分分代码,或许有助于不同层次的选手备赛. 除 ...
- CCF CSP认证菜鸟刷题日志
CCF CSP菜鸟刷题日志(c/c++) 本萌新写给自己看的,要是有大佬路过,请多多指教orz 立个flag:每日一更,至201903 9月15ccf csp,冲鸭! 今天(2019.8.18)起每天 ...
最新文章
- cmd编译java命令_使用CMD命令编译执行java命令
- Week8 Teamework from Z.XML-Z.XML游戏功能说明
- 寒冬悟道者马云:阿里巴巴逢单出击(4)
- Spring Boot结合spring-data-jpa
- pythonweb框架使用教程_Django视频教程 - 基于Python的Web框架(全13集)
- Leetcode PHP题解--D56 637. Average of Levels in Binary Tree
- 6.边缘检测:梯度——边缘检测、导数与边缘、什么是梯度_2
- 个盘子的汉诺塔需要移动几步_坨——理解递归实现quot;汉诺塔quot;代码的关键...
- 软件测试学习视频教程-精通软件测试教程
- java创建环境变量是用户还是系统_5.Java环境变量配置
- java入门到精通第六版_java从入门到精通-第6章.pdf
- java 汽车类_汽车类 - java代码库 - 云代码
- 点击自定义按钮弹出百度商桥对话框
- 蓝牙耳机一个响一个不响怎么办
- Mac版Sublime Text3搭建c语言环境
- 电脑程序是如何运行起来的
- 基于安卓的备忘录文件加密_苹果备忘录、锤子便签、印象笔记哪个更好用?
- 使用Bboss处理ES的dsl语句
- leetcode-数据结构-566. 重塑矩阵
- robotframework以手机模式打开浏览器