题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955
这题蛮有意思的,首先01背包的状态转移这些不说了,很简单。但关键这题该如何建立起01背包的模型那?如果以被抓的概率作为背包容量,由于浮点数,精度是不可靠的。
所以只能以金钱为背包容量,所以所有银行的总资产,最为背包容量,然后我们以逃跑几率进行动态转移。逃跑几率只要 用 1- p 就好了,关键一点由于是算的概率,所以逃跑
几率是想乘的,大家可以想想,不可能相加。最后我们就能完美写成代码了。(还有如果没抢到,那么概率为1 ,这也不要忽略了)
AC code:
#include <bits/stdc++.h> using namespace std; const int MAX = 10006; /*hdu2955 01背包--这里我们考虑以金钱为容量*/ int main () { int T,n,t[101]; float p,v[101]; float f[MAX]; cin>>T; while(T--) { cin >> p >> n; p = 1-p;//最低逃生几率 memset (f,0,sizeof(f)); int sum = 0; for (int i=0;i<n;++i) { cin>>t[i]>>v[i]; v[i] = 1-v[i];//这样就变成了逃生几率,逃生几率越大越好 sum +=t[i]; } f[0] = 1;//没抢到钱,逃走概率100% for (int i=0;i<n;++i) for (int j= sum;j>=t[i];--j ) { f[j] = max (f[j],f[j-t[i]]*v[i]);//这里一定要乘,因为你这是算概率,在前面逃走的概率下。 } int fg = 0; for (int i=sum;i>=0;--i) if (f[i] >= p) { fg = i;break; } cout<<fg<<endl; } return 0; } /* 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 */