HDU4815 Little Tiger vs. Deep Monkey——0-1背包
题目描述
对于n道题目,每道题目有一个分值,答对加分,答错不得分,你要和一个叫深猴的比赛,题目你可以假设成判断题(不是对就是错),深猴对于所有的题目都是随机选择一个答案,而你是有脑子的,求为了不输掉比赛(平局或你获胜)的可能性至少为p时你至少需要得到多少分,有t组数据,每次输入两行,第一行为n,p(有n道题目,n<=40, 不会输的可能性为p,0.0<=p<=1.0),第二行输入n个1~1000的整数,代表这n道题分别答对能获得的分数
样例输入
1
3 0.5
1 2 3
样例输出
3
题目分析
首先对于这n道题目,深猴每次不是√就是×,那么答完所有的题目它的分数有2^n个结果(但是这其中可能会重复,比如三道题每题一分1 0 0和0 0 1其实得到的分数是一样的),而对于我们而言,我需要求出这n个题目自己得到每一种可能的分数的可能性,然后按分数从小到大将,这得到这些分数的概率相加,直到有一个分数m时,前面相加的概率和>=p,则在分数大于等于m时,确保我有至少p的概率不会输掉比赛
错误示例
我第一次做这道题目的时候想的通过递归计算出做出n个选择之后我可以得到的每一个分数的种数存放在a数组中,a[i]代表总分为i的种数,而又建立了一个辅助数组b[i]存放分数比i小的种数有多少种,很显然b[i] = b[i-1] + a[i-1](比i小的数量等于比i-1小的数量加上a[i-1]的数量),最后也是从小到大将每一种得分的可能性相加直到大于等于p时的分数则是答案,是一种前缀和的思想,但是会超时
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
using namespace std; int k[];
int a[];
int b[];
int n;
double p; void dfs(int i, int flag, int sum){ //第i个 选or不选 前一个状态的和
if(i > n){ //只有当所有的n个都作出了选择之后才能算是一种选择方案
a[sum]++;
return;
}
if(flag == ){ //选
int next_sum = sum + k[i];
// a[next_sum]++;
dfs(i+, , next_sum);
dfs(i+, , next_sum);
}else{ //不选
int next_sum = sum;
// a[next_sum]++;
dfs(i+, , next_sum);
dfs(i+, , next_sum);
}
} void run(){
//下一个的下标 选or不选 目前为止的和
dfs(, , );
dfs(, , );
} void pre(){
b[] = ;
int end = n*;
for(int i = ; i <= end; i++){ //b[i]存放比i小的取法的数量
b[i] = b[i-] + a[i-];
}
} void judge(){
double m = ;
for(int i = ; i <= n; i++){
m *= ;
}
m *= p;
long long x = ceil(m);
int ans;
int end = n*;
for(int i = ; i <= end; i++){
if(b[i] >= x){
ans = i;
break;
}
}
printf("%d\n", ans);
} int main(){
int t;
scanf("%d", &t);
while(t--){
scanf("%d%lf", &n, &p);
memset(a, , sizeof(a));
memset(b, , sizeof(b));
for(int i = ; i <= n; i++) scanf("%d", &k[i]);
run();
pre();
judge();
}
return ;
}
正确思路
本题可以用到动态规划,0-1背包的思想,a[i]存放这n个题目的分数,dp[i][j]存放前i题,得到j分数的种数,而我们很显然可以想到,对于分数j,如果dp[i][j]可以得到,则他一定是dp[i-1][j-a[i]](第i题的分数取的种数) + dp[i-1][j](第i题的分数不取的种数)的基础上来的(对于第i题而言取的话,j == j - a[i] + a[i],不取的话就是i-1个问题,分数为j的种数,是0-1背包的问题),所以我们也可以对此用一个一维数组进行优化,dp[x]存放分数为x的种数,而初始化时dp[0] == 1,因为可以理解成前0题,得到0分的种数为1
正确代码
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
using namespace std; const int N = ;
int a[];
double dp[N];
int n;
double p; int main(){
int t;
scanf("%d", &t);
while(t--){
scanf("%d%lf", &n, &p);
int sum = ;
for(int i = ;i <= n; i++){ //sum统计最大可以得到的分数
scanf("%d", &a[i]);
sum += a[i];
}
memset(dp, , sizeof(dp));
dp[] = ; //前0题,得到0分的次数位1
for(int i = ; i <= n; i++){ //类似于0-1背包的两个循环
for(int j = sum; j >= a[i]; j--){
dp[j] += dp[j-a[i]]; //核心步骤,对于dp[j]而言,得分为j的种数是前i-1个时得分为j-a[i] 也就是取第i题,加上前i-1个时得分为j的种数 也就是不取第i题
}
}
double m = pow(,n); //统计所有的深猴的得分个数
int ans = ;
double ssum = ;
for(int i = ; i <= sum; i++){
dp[i] /= m; //从小到大将概率累加直到大于等于p时的分数i就是答案,注意0也是一个得分
ssum += dp[i];
if(ssum >= p){
ans = i;
break;
}
}
printf("%d\n", ans);
}
return ;
}
HDU4815 Little Tiger vs. Deep Monkey——0-1背包的更多相关文章
- hdu 4815 Little Tiger vs. Deep Monkey(01背包)
http://acm.hdu.edu.cn/showproblem.php?pid=4815 Description A crowd of little animals is visiting a m ...
- hdu 4815 Little Tiger vs. Deep Monkey
概率dp,有点像背包的做法: dp[i][j]代表前i个数组成的j数的概率为多少 #include<cstdio> #include<cstring> #define maxn ...
- HDU - 4815 Little Tiger vs. Deep Monkey (长春赛区C题)
题意:有A,B两个人.n道题目.每题有相应的分数.B答对题目的概率是0.5.求A不输给B的概率不小于P要拿的最低分数 思路:DP,dp[i][j]来表示B答了前i题后分数为j的概率,,然后通过B的概率 ...
- HDU 4815 Little Tiger vs. Deep Monkey(2013长春现场赛C题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4815 简单的DP题. #include <stdio.h> #include <st ...
- HDU 4815 Little Tiger vs. Deep Monkey 2013 长春现场赛C题
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4815 [题意] n个题目,每题有各自的分数,A有50%的概率答对一道题目得到相应分数,B想要在至少P的概率 ...
- poj1417 带权并查集+0/1背包
题意:有一个岛上住着一些神和魔,并且已知神和魔的数量,现在已知神总是说真话,魔总是说假话,有 n 个询问,问某个神或魔(身份未知),问题是问某个是神还是魔,根据他们的回答,问是否能够确定哪些是神哪些是 ...
- P1417 烹调方案 (0/1背包+贪心)
题目背景 由于你的帮助,火星只遭受了最小的损失.但gw懒得重建家园了,就造了一艘飞船飞向遥远的earth星.不过飞船飞到一半,gw发现了一个很严重的问题:肚子饿了~ gw还是会做饭的,于是拿出了储藏的 ...
- 洛谷 P1064 金明的预算方案 (有依赖的0/1背包)
题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱就行”. ...
- POJ 1636 Prison rearrangement DFS+0/1背包
题目链接: id=1636">POJ 1636 Prison rearrangement Prison rearrangement Time Limit: 3000MS Memor ...
随机推荐
- luoguP2852 [USACO06DEC]Milk Patterns
题意 显然如果有一个子串出现过\(k\)次,那么它必定是一个至少长为k的后缀序的\(LCP\),求出所有相邻的长为\(k-1\)的\(height\)数组的最小值,在其中取最大值即可 code: #i ...
- Python进阶-XV 类和对象的命名空间 组合
一.类和对象命名空间 1.类中可以定义两种属性 静态属性和动态属性 class Course: language = 'Chinese' # 静态属性 def __init__(self, name, ...
- vscode (1.41.0版本,1.41.1版本)node_modules部分TS声明文件@types包会导致该版本没JS语法提示
正常提示如下: 然而我的提示没了,本以为是插件问题,把所有插件禁用不行!卸载重装vscode还是不行!!但是其他电脑的1.41.1版本,同样代码确没问题!!!简直日了*了 折腾大半天,发下问题如下: ...
- AGC008E Next or Nextnext(组合计数,神奇思路)
神仙题. 排列计数,一种常见的做法是 \(i\) 向 \(p_i\) 连边. 然而这里这个就逼迫我们只能从 \(i\) 向 \(a_i\) 连边. 不过没关系,考虑从 \(i\) 向 \(p_i\) ...
- Unity 2018 Artificial Intelligence Cookbook Second Edition (Jorge Palacios 著)
https://github.com/PacktPublishing/Unity-2018-Artificial-Intelligence-Cookbook-Second-Edition 1 Beha ...
- MySQL实战45讲学习笔记:第四十一讲
一.本节概述 我在上一篇文章最后,给你留下的问题是怎么在两张表中拷贝数据.如果可以控制对源表的扫描行数和加锁范围很小的话,我们简单地使用 insert … select 语句即可实现. 当然,为了避免 ...
- 大话设计模式Python实现-备忘录模式
备忘录模式(Memento Pattern):不破坏封装性的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态,这样已经后就可将该对象恢复到原先保存的状态 下面是一个备忘录模式的demo: #! ...
- Go 程序编译成 DLL 供 C# 调用。
Go 程序编译成 DLL 供 C# 调用. C# 结合 Golang 开发 1. 实现方式与语法形式 基本方式:将 Go 程序编译成 DLL 供 C# 调用. 1.1 Go代码 注意:代码中 ex ...
- conda基本知识
卸载anaconda: rm -rf anaconda3 (anaconda文件夹名称) conda删除虚拟环境 在终端执行:conda remove -n your_env_name(虚拟环境名称) ...
- Logstash:把MySQL数据导入到Elasticsearch中
Logstash:把MySQL数据导入到Elasticsearch中 前提条件 需要安装好Elasticsearch及Kibana. MySQL安装 根据不同的操作系统我们分别对MySQL进行安装.我 ...