题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2955
Robberies
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 16598 Accepted Submission(s): 6101
For a few months now, Roy has been assessing the security of various banks and the amount of cash they hold. He wants to make a calculated risk, and grab as much money as possible.
His mother, Ola, has decided upon a tolerable probability of getting caught. She feels that he is safe enough if the banks he robs together give a probability less than this.
Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .
Notes and Constraints
0 < T <= 100
0.0 <= P <= 1.0
0 < N <= 100
0 < Mj <= 100
0.0 <= Pj <= 1.0
A bank goes bankrupt if it is robbed, and you may assume that all probabilities are independent as the police have very low funds.
3 0.04 3 1 0.02 2 0.03 3 0.05 0.06 3 2 0.03 2 0.03 3 0.05 0.10 3 1 0.03 2 0.02 3 0.05
2 4 6
入门DP(正适合我这种菜鸡。。),题意告诉你小偷不能忍受的被捕概率和几个银行,接下来是每个银行的价值和被抓概率;
一开始把概率当做背包容量相加了。。错了好久,对不起高中数学老师。。
若抢劫A银行被抓概率为p1,抢劫B银行被抓概率为p2,那么抢劫A和B银行被抓概率应该为1-(1-p1)*(1-p2)
而dp储存的是当前价值的逃生几率,那么可以推出动态方程dp[j]=max(dp[i],dp[i-val[i]]*(1-p[i]))
那么代码如下。。
#include<stdio.h>
#include<string.h>
double max(double a, double b)
{
return a > b ? a : b;
}
typedef struct node
{
int dis;
double p;
};
node nod[101];
int t;
double dp[10010];
int main()
{
// freopen("input.txt", "r", stdin);
int sum, m;
double p;
scanf("%d", &t);
while (t--)
{
memset(dp, 0, sizeof(dp)); //初始化
dp[0] = 1; //抢劫0元的逃生概率为1,这个必须要写
sum = 0;
scanf("%lf%d", &p, &m);
for (int i = 0; i < m; i++)
{
scanf("%d%lf", &nod[i].dis, &nod[i].p);
sum += nod[i].dis;
}
for (int i = 0; i < m; i++)
for (int j = sum; j >= nod[i].p; j--)
dp[j] = max(dp[j], dp[j - nod[i].dis] * (1 - nod[i].p));
for (int i = sum; i >= 0; i--)
if (1 - dp[i] < p){ //金钱从大往小遍历一边,只要被抓的概率不超过题目给的概率就输出
printf("%d\n", i);
break;
}
}
return 0;
}
594



被折叠的 条评论
为什么被折叠?



