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

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<math.h>
 5 using namespace std;
 6
 7 int k[45];
 8 int a[40005];
 9 int b[40005];
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 == 1){            //选
19         int next_sum = sum + k[i];
20 //        a[next_sum]++;
21         dfs(i+1, 1, next_sum);
22         dfs(i+1, 0, next_sum);
23     }else{                    //不选
24         int next_sum = sum;
25 //        a[next_sum]++;
26         dfs(i+1, 1, next_sum);
27         dfs(i+1, 0, next_sum);
28     }
29 }
30
31 void run(){
32     //下一个的下标 选or不选 目前为止的和
33     dfs(1, 1, 0);
34     dfs(1, 0, 0);
35 }
36
37 void pre(){
38     b[1] = 1;
39     int end = n*1000;
40     for(int i = 2; i <= end; i++){    //b[i]存放比i小的取法的数量
41         b[i] = b[i-1] + a[i-1];
42     }
43 }
44
45 void judge(){
46     double m = 1;
47     for(int i = 1; i <= n; i++){
48         m *= 2;
49     }
50     m *= p;
51     long long x = ceil(m);
52     int ans;
53     int end = n*1000;
54     for(int i = 1; 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, 0, sizeof(a));
69         memset(b, 0, sizeof(b));
70         for(int i = 1; i <= n; i++) scanf("%d", &k[i]);
71         run();
72         pre();
73         judge();
74     }
75     return 0;
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 = 40005;
 8 int a[45];
 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 = 0;
19         for(int i = 1;i <= n; i++){        //sum统计最大可以得到的分数
20             scanf("%d", &a[i]);
21             sum += a[i];
22         }
23         memset(dp, 0, sizeof(dp));
24         dp[0] = 1;                //前0题,得到0分的次数位1
25         for(int i = 1; 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(2,n);        //统计所有的深猴的得分个数
31         int ans = 0;
32         double ssum = 0;
33         for(int i = 0; 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 0;
44 }

原文地址:https://www.cnblogs.com/findview/p/11372951.html

时间: 2024-11-14 12:22:34

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

Little Tiger vs. Deep Monkey(01背包)

Little Tiger vs. Deep Monkey Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 3715    Accepted Submission(s): 1276 Problem Description A crowd of little animals is visiting a mysterious laborator

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 mysterious laboratory ? The Deep Lab of SYSU. “Are you surprised by the STS (speech to speech) technology of Microsoft Research and the cat face recogn

HDOJ 4815 Little Tiger vs. Deep Monkey

递推... Little Tiger vs. Deep Monkey Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 661    Accepted Submission(s): 244 Problem Description A crowd of little animals is visiting a mysterious labo

HDU 4815 Little Tiger vs. Deep Monkey

http://acm.hdu.edu.cn/showproblem.php?pid=4815 题意: 给定N个题目各自的分数a[i] A有50%的概率答对一道题目得到相应分数,B想要在至少P的概率上总分不低于A 问B至少要得到多少分 解法: 概率DP dp[i][j]表示前i题得到j分的概率 递推式: dp[i][j] = dp[i-1][j] * 0.5 (a[i]>j) dp[i][j] = (dp[i-1][j] + dp[i-1][j - a[i]]) * 0.5 (a[i]<=j)

HDU 4815 Little Tiger vs. Deep Monkey 背包问题

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4815 题意:很"内涵"的一个题面,题意是给出N道题,和一个概率P,然后给出每道题对应的得分aa[i](每道题只有两个选项,一个正确一个错误).两个人来答题,一个人是随机选择答案,问另一个人至少要答多少分才能保证有P的概率不会失败. 思路:是一道DP题,最开始想强行枚举所有情况,找到需要分数,后来发现40道题强行枚举2^40必然超时,思路就中断了,后来想到DP,刚开始DP的可能得到的分数,但是很

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

题意:有一个岛上住着一些神和魔,并且已知神和魔的数量,现在已知神总是说真话,魔总是说假话,有 n 个询问,问某个神或魔(身份未知),问题是问某个是神还是魔,根据他们的回答,问是否能够确定哪些是神哪些是魔. 对于这些问题,我们只需要发现,如果回答对方是魔,那么即可以判断出这两个不是同一种族,而如果回答对方是神,那么说明这两个是同一种族,那么就可以用带权并查集合并这些神和魔,然后记录两种分别多少个,这样当所有询问都处理完时我们就可以得到一系列的集合,每个集合分别有它的两个种族的人数,但是此时对于每个

NOJ 1860 保研(0/1背包概率dp)

保研 时间限制(普通/Java):1000MS/3000MS         运行内存限制:65536KByte 总提交:171          测试通过:40 题目描述 对于一些名校而言,保研不仅可以由学校推免,也可以由学生自己向希望保研的学校提出申请,这个过程有点类似于外国学生向学校提交简历等待Offer的过程.但是,投递申请需要亲自去相应学校的研招办递交材料,这就需要一些成本(比如路费等),且每个院校都有自己的录取成功率.现在,请在总成本不超过限制的情况下,求出最大的成功率. 输入 输入

POJ 1636 Prison rearrangement DFS+0/1背包

题目链接: POJ 1636 Prison rearrangement Prison rearrangement Time Limit: 3000MS   Memory Limit: 10000K Total Submissions: 2194   Accepted: 984 Description In order to lower the risk of riots and escape attempts, the boards of two nearby prisons of equal

POJ 3628 Bookshelf 2 0/1背包和DFS两种解法

题目链接:POJ 3628 Bookshelf 2 Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7462   Accepted: 3436 Description Farmer John recently bought another bookshelf for the cow library, but the shelf is getting filled up quite quickly,