hdu2955 - Robberies
题链:http://acm.hdu.edu.cn/showproblem.php?pid=2955
抢银行有风险,入抢需谨慎!
本题就是要你计算在某个风险允许的范围内,这个叫兽最多能抢多少钱,给出了每个银行的风险和金额;
一开始大家肯定有这么一个直觉,风险为背包,但是这就有两个问题:
风险是小数,不好比较大小,其次,风险之间不是简单的相加减;
最好的两个思想:化险为安,风险不好算,可是安全度好算,他们是简单的相乘关系;
核心:
for ( i = 0 ; i < n ; i ++ ){
for ( j = v ; j >= a[i] ; j-- ){f[j] = f[j] > ( f[j-a[i]] * b[i] ) ? f[j] : ( f[j-a[i]] *b[i] ) ;
}
}
以钱为背包,然后去找出在安全范围内钱数最大的背包
for( i = v ; i >=0 ; i-- ){
if( f[i]-m>=0.000000001 ){
printf( "%d\n" , i ) ;
break ;
}
}
#include
#include
int n;
int a[10000];
double f[10000],m,b[10000],v;
void Init()
{
int i ;
v = 0 ;
for ( i = 0 ; i < n ; i++ ){
scanf("%d%lf", &a[i] , &b[i] ) ;
v += a[i] ;
b[i] = 1 - b[i] ;
}
for ( i = 1 ; i <= v ; i++ ){
f[i] = 0 ;
}
f[0] = 1 ;
}
void grab()
{
int i , j ;
for ( i = 0 ; i < n ; i ++ ){
for ( j = v ; j >= a[i] ; j-- ){
f[j] = f[j] > ( f[j-a[i]] * b[i] ) ? f[j] : ( f[j-a[i]] *b[i] ) ;
}
}
for( i = v ; i >=0 ; i-- ){
if( f[i]-m>=0.000000001 ){
printf( "%d\n" , i ) ;
break ;
}
}
}
int main()
{
int T ;
scanf("%d",&T);
while ( T -- ){
scanf("%lf%d",&m,&n) ;
m = 1 - m ;
Init();
grab();
}
return 0;
}