hdu2955 Robberies(01背包)
来源:互联网 发布:php postgresql 编辑:程序博客网 时间:2024/05/22 15:27
只有我一个人觉得这题题意很难懂么。。。
先是给出几组数据,每组数据第一行是总被抓概率p(最后求得的总概率必须小于他,否则被抓),然后是想抢的银行数n。然后n行,每行分别是该银行能抢的钱数m[i]和被抓的概率p[i],求最大逃跑概率。被抓的概率越大,逃跑概率越小。
第一点就是最容易犯错的一点,把所求总被抓概率看成背包容量。这就有两个很明显错误,求的就是1-被抓概率=逃跑概率,限制条件和最大背包容量不能同为一属性。再者,概率为多为浮点数,精确度不高无法遍历。所以背包容量必然是钱数,因为他能抢的银行有限,钱数也是有限的。然后是求最大逃跑概率,而题中每项给出的是被抓概率,所以要先被1减一下。还有最后求得的逃跑概率随着抢银行的数量增加而减少,多抢一个银行,其钱数必将转化为概率的乘积,所以动态方程也要做出改变。最后遍历,剩余的钱数越多,说明所抢的钱数越少,逃跑几率越大。所以从大到小遍历背包容量,一旦大于p,即为最大概率跳出。
这应该是写的比较场的体会了,主要是这题多想想还是蛮有意思的~
#include <stdio.h>#include <algorithm>#include <iostream>#include <cmath>#include <string.h>using namespace std;const int N = 50005;int main(){ // freopen("in.txt", "r", stdin); int t, m0, m[N]; double p0, p[N], ans[N]; scanf("%d", &t); while(t --) { scanf("%lf%d", &p0, &m0); int sum = 0; for(int i = 0; i < m0; i ++) { scanf("%d%lf", &m[i], &p[i]); sum += m[i]; } memset(ans, 0, sizeof(ans)); ans[0] = 1; for(int i = 0; i < m0; i ++) { for(int j = sum; j >= m[i]; j --) { ans[j] = max(ans[j], ans[j - m[i]] *(1 - p[i])); } } for(int i = sum; i >= 0; i --) { if(ans[i] > (1 - p0)) { printf("%d\n", i); break; } } } return 0;}
0 0
- hdu2955---Robberies(01背包)
- hdu2955 Robberies (01背包)
- hdu2955 Robberies(01背包)
- hdu2955 Robberies(01背包)
- hdu2955 Robberies(01背包)
- Robberies hdu2955 01背包
- HDU2955:Robberies(01背包)
- hdu2955 Robberies (01背包)
- HDU2955 Robberies 01背包
- HDU2955-Robberies-01背包
- hdu2955 Robberies --01背包
- hdu2955 01背包 Robberies
- HDU2955 Robberies(01背包)
- hdu2955 — Robberies (01背包)
- hdu2955-Robberies(01背包 概率 )
- hdu2955 robberies题解(01背包)
- hdu2955 Robberies(01背包)题解
- hdu2955 Robberies 01背包 dp
- iOS极光整合
- 按钮带动画效果(1)
- 设计模式之单例模式
- 这是我的第一篇博客
- 用两个栈实现队列
- hdu2955 Robberies(01背包)
- 基本标签(一)
- Java笔记2:使用命令行编译运行“Helloworld”
- 工厂方法模式(Factory Method)
- getloadavg()函数
- RedHat 6 系统 使用网易源
- 关于Java字符串String在运算中的拼接
- acm1016
- UVA 10891【区间dp】