HDU 2955
这是一道01背包的问题,但是有一个地方我没有想到,所以花了很多时间。
题目给了每个银行的钱和被抓的概率,由于要抢尽量多的钱,所以要保证尽量不被抓,而抢多个银行之后不被抓的概率是抢每一个银行不被抓的概率之积,我竟然把这一点给忘了!导致我走了许多弯路,思路不能太死啊!dp[]表示抢到下标所对应的钱时,此时不被抓的概率,题目给出了最终不能高于被抓概率P,不被抓的概率就不能低于(1-P),所以最后只需要逆序遍历dp,找到第一个大于等于1-P的dp[i],就能够保证i最大,即抢到的钱最多。
#include<stdio.h> #include<string.h> #define MAX_LMT 10000 float max(float,float); int main() { int t,money[MAX_LMT]; float prob[MAX_LMT],dp[MAX_LMT]; scanf("%d",&t); while(t--) { float P; int n,i,j,total=0; scanf("%f%d",&P,&n); for(i=1;i<=n;i++) { scanf("%d%f",&money[i],&prob[i]); total+=money[i]; } memset(dp,0,sizeof(dp)); dp[0]=1; for(i=1;i<=n;i++) { for(j=total;j>=money[i];j--) { dp[j]=max(dp[j],dp[j-money[i]]*(1-prob[i])); } } for(i=total;i>=0;i--) { if(dp[i]>=(1-P)) { printf("%d\n",i); break; } } } return 0; } float max(float x,float y) { return x>y?x:y; }