题目描述

对于n道题目,每道题目有一个分值,答对加分,答错不得分,你要和一个叫深猴的比赛,题目你可以假设成判断题(不是对就是错),深猴对于所有的题目都是随机选择一个答案,而你是有脑子的,求为了不输掉比赛(平局或你获胜)的可能性至少为p时你至少需要得到多少分,有t组数据,每次输入两行,第一行为n,p(有n道题目,n<=40, 不会输的可能性为p,0.0<=p<=1.0),第二行输入n个1~1000的整数,代表这n道题分别答对能获得的分数

样例输入

  1. 1
  2. 3 0.5
  3. 1 2 3

样例输出

  1. 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时的分数则是答案,是一种前缀和的思想,但是会超时

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<math.h>
  5. using namespace std;
  6.  
  7. int k[];
  8. int a[];
  9. int b[];
  10. int n;
  11. double p;
  12.  
  13. void dfs(int i, int flag, int sum){ //第i个 选or不选 前一个状态的和
  14. if(i > n){ //只有当所有的n个都作出了选择之后才能算是一种选择方案
  15. a[sum]++;
  16. return;
  17. }
  18. if(flag == ){ //选
  19. int next_sum = sum + k[i];
  20. // a[next_sum]++;
  21. dfs(i+, , next_sum);
  22. dfs(i+, , next_sum);
  23. }else{ //不选
  24. int next_sum = sum;
  25. // a[next_sum]++;
  26. dfs(i+, , next_sum);
  27. dfs(i+, , next_sum);
  28. }
  29. }
  30.  
  31. void run(){
  32. //下一个的下标 选or不选 目前为止的和
  33. dfs(, , );
  34. dfs(, , );
  35. }
  36.  
  37. void pre(){
  38. b[] = ;
  39. int end = n*;
  40. for(int i = ; i <= end; i++){ //b[i]存放比i小的取法的数量
  41. b[i] = b[i-] + a[i-];
  42. }
  43. }
  44.  
  45. void judge(){
  46. double m = ;
  47. for(int i = ; i <= n; i++){
  48. m *= ;
  49. }
  50. m *= p;
  51. long long x = ceil(m);
  52. int ans;
  53. int end = n*;
  54. for(int i = ; i <= end; i++){
  55. if(b[i] >= x){
  56. ans = i;
  57. break;
  58. }
  59. }
  60. printf("%d\n", ans);
  61. }
  62.  
  63. int main(){
  64. int t;
  65. scanf("%d", &t);
  66. while(t--){
  67. scanf("%d%lf", &n, &p);
  68. memset(a, , sizeof(a));
  69. memset(b, , sizeof(b));
  70. for(int i = ; i <= n; i++) scanf("%d", &k[i]);
  71. run();
  72. pre();
  73. judge();
  74. }
  75. return ;
  76. }

正确思路

本题可以用到动态规划,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

正确代码

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<math.h>
  4. #include<string.h>
  5. using namespace std;
  6.  
  7. const int N = ;
  8. int a[];
  9. double dp[N];
  10. int n;
  11. double p;
  12.  
  13. int main(){
  14. int t;
  15. scanf("%d", &t);
  16. while(t--){
  17. scanf("%d%lf", &n, &p);
  18. int sum = ;
  19. for(int i = ;i <= n; i++){ //sum统计最大可以得到的分数
  20. scanf("%d", &a[i]);
  21. sum += a[i];
  22. }
  23. memset(dp, , sizeof(dp));
  24. dp[] = ; //前0题,得到0分的次数位1
  25. for(int i = ; i <= n; i++){ //类似于0-1背包的两个循环
  26. for(int j = sum; j >= a[i]; j--){
  27. dp[j] += dp[j-a[i]]; //核心步骤,对于dp[j]而言,得分为j的种数是前i-1个时得分为j-a[i] 也就是取第i题,加上前i-1个时得分为j的种数 也就是不取第i题
  28. }
  29. }
  30. double m = pow(,n); //统计所有的深猴的得分个数
  31. int ans = ;
  32. double ssum = ;
  33. for(int i = ; i <= sum; i++){
  34. dp[i] /= m; //从小到大将概率累加直到大于等于p时的分数i就是答案,注意0也是一个得分
  35. ssum += dp[i];
  36. if(ssum >= p){
  37. ans = i;
  38. break;
  39. }
  40. }
  41. printf("%d\n", ans);
  42. }
  43. return ;
  44. }

HDU4815 Little Tiger vs. Deep Monkey——0-1背包的更多相关文章

  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 ...

  2. hdu 4815 Little Tiger vs. Deep Monkey

    概率dp,有点像背包的做法: dp[i][j]代表前i个数组成的j数的概率为多少 #include<cstdio> #include<cstring> #define maxn ...

  3. 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的概率 ...

  4. HDU 4815 Little Tiger vs. Deep Monkey(2013长春现场赛C题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4815 简单的DP题. #include <stdio.h> #include <st ...

  5. HDU 4815 Little Tiger vs. Deep Monkey 2013 长春现场赛C题

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4815 [题意] n个题目,每题有各自的分数,A有50%的概率答对一道题目得到相应分数,B想要在至少P的概率 ...

  6. poj1417 带权并查集+0/1背包

    题意:有一个岛上住着一些神和魔,并且已知神和魔的数量,现在已知神总是说真话,魔总是说假话,有 n 个询问,问某个神或魔(身份未知),问题是问某个是神还是魔,根据他们的回答,问是否能够确定哪些是神哪些是 ...

  7. P1417 烹调方案 (0/1背包+贪心)

    题目背景 由于你的帮助,火星只遭受了最小的损失.但gw懒得重建家园了,就造了一艘飞船飞向遥远的earth星.不过飞船飞到一半,gw发现了一个很严重的问题:肚子饿了~ gw还是会做饭的,于是拿出了储藏的 ...

  8. 洛谷 P1064 金明的预算方案 (有依赖的0/1背包)

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过NN元钱就行”. ...

  9. POJ 1636 Prison rearrangement DFS+0/1背包

    题目链接: id=1636">POJ 1636 Prison rearrangement Prison rearrangement Time Limit: 3000MS   Memor ...

随机推荐

  1. python3.5.3rc1学习四:类

    class calculator: def add(x,y): return x + y print(added) def sub(x,y): return x - y print(sub) def ...

  2. java中的字符串二

    public class TestString { public static void main(String[] args) { // TODO Auto-generated method stu ...

  3. cookiecutter

    1.安装cookiecutter pip3 install cookiecutter 2.设置模板 https://github.com/cookiecutter/cookiecutter   搜索需 ...

  4. Ultimate Chicken Horse GameProject第三次迭代成果文档

    经过三次迭代我们实现了游戏的基本功能 项目文档的github链接:https://github.com/k6tok12355/Ultimate-Chicken-Horse 下面是我们在第一次迭代中设定 ...

  5. CF-weekly4 D. Haar Features

    https://codeforces.com/gym/253910/problem/D D. Haar Features time limit per test 1 second memory lim ...

  6. Token认证,如何快速方便获取用户信息

    背景 我们有一个Web项目,这个项目提供了很多的Rest API.也做了权限控制,访问API的请求必须要带上事先认证后获取的Token才可以. 认证的话就在Filter中进行的,会获取请求的Token ...

  7. WIFI Portal登录

    开头 关于 ANDROID 5.0-7.1.2 网络图标上的感叹号及其解决办法-狐狸的小小窝 HTTP状态码之204 No Content 原理 访问generate_204地址,如果得到状态码是20 ...

  8. 物联网架构成长之路(37)-基于C#开发串口工具

    0. 前言 作为物联网平台开发,最基础的工具链还是要有的.前几篇博客,介绍了用C#开发一个MQTT的客户端,用于模拟设备连接平台,并发送数据到平台.但是对于一些硬件来说,可能会用到串口uart来发送数 ...

  9. mybatis的参数传递

    mybatis的参数传递分为两种:1.单参数传递  2.多参数传递 单参数 mybatis会直接取出参数值给Mapper文件赋值 例子如下: 1.Mapper文件内容如下: public void d ...

  10. Java的POJO和JavaBean的区别

    POJO Plain Ordinary Java Object,即简单的java对象. 特点 需要有一些 private 的参数,以及针对参数的 setter 和 getter 方法来访问这些参数. ...