本题的题意为:一个贼想抢银行,然后给出被抓的概率的和 和测试样例的个数N,然后下面N行每行为每次偷的钱数和被抓的概率。
解题的思路:很明显这题考察的是01背包,然后我一开始本来想用贪心,结果想想必然是不能的,所以得用动态规划做,动态规划得有边界吧,边界是什么?当然是能偷的钱数啦,它是有封顶的哈,所以统计一下贼最多可以抢的钱,然后有了这个思路可以套用01背包的核心代码:
for i=1..N
forv=V..0
f[v]=max{f[v],f[v-c[i]]+w[i]};
演变一下变为本题的核心代码:
for i=1..N
forv=sum..0
f[v]=max{f[v],f[v-c[i]]*w[i]}; //w[i]为成功率 ,c[i]为第i个的钱数
下面为本题的完整代码:
#include
#include
#include
#include
using namespace std;
const int maxn = 10000;
double dp[maxn]; //成功率
struct Map
{
int value;
double rate;
} p[maxn];
/*bool cmp(struct Map a,struct Map b)
{
return (1-a.rate) * a.value > (1-b.rate) * b.value;
}*/
int main()
{
int T,m,i,j,sum; //m为样例个数
double total;
//freopen("1","r",stdin);
cin>>T;
while(T--)
{
sum = 0;
cin>>total>>m;
for(i=0; i>p[i].value>>p[i].rate; //每次能偷的钱数和被抓的概率
sum += p[i].value; //总的能偷的钱数
}
for(i=0;i<=sum;i++)
{
dp[i] = 0;
}
dp[0]= 1; //因为没偷所以不会被抓,所以成功率为百分之百
//sort(p+1,p+m+1,cmp);
/*for(i=1;i<=m;i++)
{
cout<=p[i].value;j--)
{
dp[j] = max(dp[j],dp[j-p[i].value]*(1-p[i].rate)); //拿了该件物品的价值乘以成功率
//cout<=0;i--)
{
if(dp[i] - (1-total) > 0.000001) //从能偷的最大钱开始从大到小遍历,一旦发现不会被抓的数就输出,然后结束
{
cout<