http://acm.hdu.edu.cn/showproblem.php?pid=2955
(1)概率的预处理(常识):rp[i]=1-rp[i],并将概率相乘。若将概率相加(定式思维),案例是可以全过的,就麻烦了。。
(2)初始化dp数组:偷走0百万是安全的,这很关键(dp[0]=1),其他的都是危险的(dp[i]=0),因为背包必须装满;
(3)用sum 记录最大可能出现的值,结果也是从sum开始验证,符合安全条件的输出。
具体代码:
View Code
#include<stdio.h> #include<stdio.h> #include<algorithm> using namespace std; int n, m[120]; float p, rp[120]; float dp[10100]; int main() { int i, j, t, sum; while(scanf("%d", &t)!=EOF) { while(t--) { scanf("%f%d", &p, &n), p=1-p; sum=0; for(i=1;i<=n;i++) scanf("%d%f", &m[i], &rp[i]), sum+=m[i], rp[i]=1-rp[i]; for(i=0;i<=sum;i++) dp[i]=0; dp[0]=1; for(i=1;i<=n;i++) for(j=sum;j>=m[i];j--) dp[j]=max(dp[j], dp[j-m[i]]*rp[i]); for(i=sum;i>=0;i--) if(dp[i]>p) break; printf("%d\n", i); } } return 0; }
