hdu2955之01背包

http://acm.hdu.edu.cn/showproblem.php?pid=2955

题意简述:一个小偷要去抢银行,每个银行有两个值,分别为钱的数量和被抓的概率,劫匪要保证在给定的被抓的概率内抢到最多的钱。

                首先输入一个概率p代表劫匪在抢钱时被抓的概率小于p是就可以抢银行,输入n代表n个银行,接下来n行每行有两个数分别为该银行的钱数和被抓的概率.

思路:        假设总共抢了j元钱,被抓概率为DP[j],这j元钱里是否抢了第i个个银行,假设第i个银行有value[i][0]元,被抓的概率为value[i][1],所以DP[j] = min ( DP[j] , 1- ( 1-DP[j-value[0]] ) * ( 1-value[i][1] ) ).





#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<iomanip>
#define INF 99999999
using namespace std;

const int MAX=101;
double dp[MAX*MAX],value[MAX][2];//dp是记录抢n元钱被抓的概率.

int main(){
	int n,t;
	double p;
	cin>>t;
	while(t--){
		cin>>p>>n;
		int all=0,max_money=0;//记录最终可以抢的最多的钱和所有银行钱的总和. 
		for(int i=0;i<n;++i)cin>>value[i][0]>>value[i][1],max_money+=(int)value[i][0];
		for(int i=1;i<=max_money;++i)dp[i]=1;//初始化抢任何多的钱被抓的概率都是1(dp[0]=0).
		for(int i=0;i<n;++i){//抢第i个银行. 
			for(int j=max_money;j>=value[i][0];--j){//在抢第i个银行的情况下假设劫匪总共抢了多少钱. 
				dp[j]=min(dp[j],1-(1-dp[j-(int)value[i][0]])*(1-value[i][1]));
				if(dp[j]<=p)all=max(all,j);
			}
		} 
		cout<<all<<endl;
	}
	return 0;
} 


你可能感兴趣的:(hdu2955之01背包)