首先想明白怎么计算概率,就是计算他的逆事件,也就是算失败概率然后用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; }