您的位置:首页 > Web前端

HDU 1203 I NEED A OFFER!(01背包)

2015-08-17 21:24 441 查看
题目地址:点击打开链接

思路:刚开始没想到是01背包,看了别人的解题报告才懂的,算是一道好题吧,和普通背包放东西有点不一样,需要从对立面思考,正面情况太多,求1减去份 也收不到的概率即可

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int cost[10001];
double value[10001],dp[10001];

int main()
{
int n,m,i,j;
while(scanf("%d%d",&n,&m))
{
memset(dp,0,sizeof(dp));
if(n + m == 0)
break;
for(i=0; i<m; i++)
{
scanf("%d%lf",&cost[i],&value[i]);
}
for(i=0; i<=n; i++)
{
dp[i] = 1.0;
}
for(i=0; i<m; i++)
{
for(j=n; j>=cost[i]; j--)
{
dp[j] = min(dp[j],dp[j-cost[i]] * (1 - value[i]));
}
}
printf("%.1lf%%\n",(1-dp
)*100);
}
return 0;
}

训练赛又练了一遍,发现还是不太熟练,把我写注解的代码贴上来吧

AC代码2:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

typedef long long ll;
using namespace std;

double dp[10010];

int main()
{
int n,m,i,j;
while(scanf("%d%d",&n,&m))
{
if(n + m == 0)
break;
for(i=0; i<=n; i++)//记得从0开始
{
dp[i] = 1.0;
}
int cost;
double value;
for(i=0; i<m; i++)
{
scanf("%d%lf",&cost,&value);
value = 1.0 - value;
for(j=n; j>=cost; j--)
{
dp[j] = min(dp[j],dp[j-cost] * value);//因为j-cost有可能为0,所以dp得从0开始
}
}
printf("%.1lf%%\n",(1-dp
)*100);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: