HDU 1203:I NEED A OFFER!

首先想明白怎么计算概率,就是计算他的逆事件,也就是算失败概率然后用1减

然后很自然的得到递推式

dp[v] = min(dp[v], dp[v-c[i]]*(1-w[i])

dp[v]状态的值表示当前状态下的失败概率

注意dp数组初始化为1

附代码

HDU 1203:I NEED A OFFER!
/*************************************************************************
    > File Name:    hdu1203.cpp
    > Author:       Shine
    > Created Time: 2013-05-10 下午 2:33:19
    > QuestionType: 01背包
    > Way: dp[v] = min(dp[v], dp[v-c[i]]*(1-w[i])) 状态值含义为当前状态失败概率
    > Submit: 1A
    > Gain: 01背包变形应用(不一定是和)
    > Experience: 拿或不拿像背包
 ************************************************************************/
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))

double f[10010];
int c[10010];
double w[10010];

int main() {
    int g,m;
    while (scanf("%d%d", &g, &m) && !(g==0 && m==0)) {
        int i;
        for (i = 0; i < 10010; i++) {
            f[i] = 1;
        }
        for (i = 0; i < m; i++) {
            scanf("%d%lf", &c[i], &w[i]);
            int j;
            for (j = g; j >= c[i]; j--) {
                f[j] = min(f[j], f[j-c[i]]*(1-w[i]));
            }
        }

        printf("%.1lf%%\n", (1-f[g])*100.0);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/shinecheng/p/3071181.html