题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2955
Robberies
Memory Limit: 32768/32768 K (Java/Others)
输入
The first line of input gives T, the number of cases. For each scenario, the first line of input gives a floating point number P, the probability Roy needs to be below, and an integer N, the number of banks he has plans for. Then follow N lines, where line j gives an integer Mj and a floating point number Pj .
Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .
输出
For each test case, output a line with the maximum number of millions he can expect to get while the probability of getting caught is less than the limit set.
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
题意
小偷偷第i家银行能获利mi,被抓的概率为pi,各银行被抓概率独立,如果小偷被抓概率超过p,小偷就被抓,问小偷不被抓的最大获利。
题解
首先,概率没法做容量,我们只能考虑用钱做容量,dp[i]表示获利为i的最小被抓概率。
注意:已知i银行被抓概率为pi,j银行被抓概率为pj,则同时偷两银行概率为:pi+pj-pi*pj。
代码
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-6;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=11111;
int n,mon[111];
double pr,pro[111];
double dp[maxn];
int main() {
int tc;
scf("%d",&tc);
while(tc--){
scf("%lf%d",&pr,&n);
for(int i=1;i<=n;i++){
scf("%d%lf",mon+i,pro+i);
}
rep(i,0,maxn) dp[i]=2.0;
dp[0]=0.0;
for(int i=1;i<=n;i++){
for(int j=maxn-1;j>=mon[i];j--){
dp[j]=min(dp[j],dp[j-mon[i]]+pro[i]-dp[j-mon[i]]*pro[i]);
}
}
int ans=0;
for(int j=maxn-1;j>=0;j--){
if(dp[j]<=eps+pr){
ans=j; break;
}
}
prf("%d
",ans);
}
return 0;
}
//end-----------------------------------------------------------------------
Notes
这题应该注意到独立概率的关键字!!!我竟然没有容斥直接拿去加了,概率渣xrz.