背包;第一次做的时候把概率当做背包(放大100000倍化为整数):在此范围内最多能抢多少钱 最脑残的是把总的概率以为是抢N家银行的概率之和… 把状态转移方程写成了f[j]=max{f[j],f[j-q[i].v]+q[i].money}(f[j]表示在概率j之下能抢的大洋);
正确的方程是:f[j]=max(f[j],f[j-q[i].money]*q[i].v) 其中,f[j]表示抢j块大洋的最大的逃脱概率,条件是f[j-q[i].money]可达,也就是之前抢劫过;
始化为:f[0]=1,其余初始化为-1 (抢0块大洋肯定不被抓嘛)
#include <iostream> using namespace std; typedef struct node { int x;double y; }bank; int main() { int t,n,i,j; bank p[102]; double P,f[10005]; cin>>t; while (t--) { cin>>P>>n; i=0; int k; int sum=0; for (i=0;i<n;i++) { cin>>p[i].x>>p[i].y; if (p[i].y<=P) { sum+=p[i].x; } } memset(f,0,sizeof(f)); f[0]=1; for (i=0;i<n;i++) { for (k=sum;k>=p[i].x;k--) { if (f[k-p[i].x]>0 && f[k-p[i].x]*(1-p[i].y)>f[k]) { f[k]=f[k-p[i].x]*(1-p[i].y); } } } for (k=sum;k>=0;k--) { if (f[k]>(1-P)) { cout<<k<<endl; break; } } } return 0; }