lightoj 1079 Just another Robbery
题意:给出银行的个数和被抓概率上限。在给出每个银行的钱和抢劫这个银行被抓的概率。求不超过被抓概率上线能抢劫到最多的钱。
dp题,转移方程 dp[i][j] = min(dp[i-1][j] , dp[i-1][j-v[i]]) ,dp[i][j]表示前 i 个银行抢劫到 j 这么多钱被抓的概率。
初始化时 dp[0][0] = 0 , 因为 dp[0][1~n]是不可能的情况,dp[0][1~n]=-1。
#include<stdio.h> #define maxn 110 #define min(a,b) (a)>(b)?(b):(a) double a[maxn]; int v[maxn]; double f[maxn][maxn*maxn]; int main() { int T,cas=1; int n; double p; int sum; scanf("%d",&T); while(T--) { sum=0; scanf("%lf%d",&p,&n); for(int i=1;i<=n;i++) scanf("%d%lf",&v[i],&a[i]),sum+=v[i]; for(int i=1;i<=sum;i++) f[0][i]=-1; f[0][0]=0; for(int i=1;i<=n;i++) for(int j=0;j<=sum;j++) { if(j-v[i]<0 || f[i-1][j-v[i]]<-0.5) f[i][j]=f[i-1][j]; else if(f[i-1][j]<0) f[i][j]=f[i-1][j-v[i]]+(1-f[i-1][j-v[i]])*a[i]; else f[i][j]=min(f[i-1][j],f[i-1][j-v[i]]+(1-f[i-1][j-v[i]])*a[i]); } int ans=0; for(int i=0;i<=sum;i++) if(f[n][i]>-0.5 && f[n][i]<p) ans=i; printf("Case %d: %d\n",cas++,ans); } return 0; }