http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4439
C++版本一
题解:
概率背包问题
套模板就行,emmm max改成min计算不能中奖的概率
/*
*@Author: STZG
*@Language: C++
*/
#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
#include<map>
#include<set>
//#define DEBUG
using namespace std;
typedef long long ll;
const int N=1000+10;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m;
int a[N];
double b[N];
double dp[N];
int main()
{
#ifdef DEBUG
freopen("input.in", "r", stdin);
//freopen("output.out", "w", stdout);
#endif
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;i++){
scanf("%d%lf",&a[i],&b[i]);
b[i]=1-b[i];
}
for(int i=0;i<=m;i++){
dp[i]=1;
}
for(int i=1;i<=n;i++){
for(int j=m;j>=a[i];j--){
dp[j]=min(dp[j],dp[j-a[i]]*b[i]);
}
}
printf("%.4f\n",1-dp[m]);
}
//cout << "Hello world!" << endl;
return 0;
}
C++版本二
题解:
这题求一个中奖的最大概率可以转换为求一次都没有中奖的概率,然后用1减去这个概率就是中奖的概率;那么就可以转换成背包问题,维护一个最小的不中奖的概率;也就是dp【j】 = min(dp【j】,dp[j-a[i]]*pi[i]); pi[i]是不中奖的概率
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+5;
double dp[N],pi[N];
int a[N];
int main()
{
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i = 1; i <= n; i ++){
scanf("%d%lf",&a[i],&pi[i]);
pi[i] = 1-pi[i];
}
for(int i = 0; i <= m; i ++) dp[i] = 1;
for(int i = 1; i <= n; i ++){
for(int j = m; j >= a[i]; j --){
dp[j] = min(dp[j],dp[j-a[i]]*pi[i]);
}
}
printf("%.4f\n",1-dp[m]);
}
return 0;
}
C++版本三
#include<bits/stdc++.h>
using namespace std;
double dp[10005][10005];
double pi[10005];
int a[10005];
int main()
{
// freopen("data.in","r",stdin);
// freopen("text1.out","w",stdout);
int n,m;
while(~scanf("%d%d",&n,&m)){
for(int i = 1; i <= n; i ++){
scanf("%d%lf",&a[i],&pi[i]);
pi[i] = 1-pi[i];
}
for(int i = 0; i <= m; i ++)dp[0][i] = 1;
for(int i = 1; i <= n; i ++){
for(int j = 0; j < a[i]; j ++) dp[i][j] = dp[i-1][j];
for(int j = a[i]; j <= m; j ++)
dp[i][j] = min(dp[i-1][j],dp[i-1][j-a[i]]*pi[i]);
}
printf("%.4f\n",1-dp[n][m]);
}
return 0;
}
C++版本四
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
double dp[N];
int main()
{
// freopen("data.in", "r", stdin);
// freopen("check1.out", "w", stdout);
int n, m;
while(~scanf("%d%d", &n, &m)){
for(int i = 0; i <= m; ++i) dp[i] = 0.0;
int x;
double p;
for(int i = 1; i <= n; ++i){
scanf("%d%lf", &x, &p);
for(int i = 0; i <= m - x; ++i){
dp[i] = max(dp[i], dp[i + x] + (1 - dp[i + x]) * p);
}
}
printf("%.4f\n", dp[0]);
}
return 0;
}