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;
}

 

posted @ 2013-08-09 23:36  yongren1zu  阅读(277)  评论(0编辑  收藏  举报