HDU 1203 I NEED A OFFER!

传送门

01背包,价值是概率连乘。

首先,给的都是某学校被录取的概率,问的是总体被录取的最大概率,所以要转化为都不被录取的最小概率。
dp[j]表示(在前i个学校可选取的情况下,)使用的申请费总额不超过j的情况下不被任何一家录取的最小概率。
所以初始的dp值都是1.0

本题和HDU 2955的区别在于,前者求最小概率,后者求最大概率。因而要采取不同的策略:

  1. 本题:因为价值是概率连乘,只会越来越小,而且是求解最小价值(最小概率),两者的方向一致。所以无需限制恰好装满。只需要把所有dp[]初始为1.0就可以了。
  2. HDU 2955是求最大概率,两者的方向不一致。所以要限制恰好装满,否则dp值不会被更新。需要把初始时唯一的合法状态dp[0]设为合法值1.0,其余都设为非法值0.0

以上策略与普通01背包(价值是相加)是相反的。


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <queue>
using namespace std;

int N, M;
int w[10001];
double p[10001];
double dp[10001];

void init()
{
	for (int i = 0; i <= M; i++)
		dp[i] = 1.0;
}

int main()
{
	for (; ~scanf("%d%d", &M, &N);)
	{
		if (M == 0 && N == 0) break;
		init();
		for (int i = 1; i <= N; i++)
		{
			scanf("%d%lf", &w[i], &p[i]);
			p[i] = 1.0 - p[i];
		}

		for (int i = 1; i <= N; i++)
			for (int j = M; j >= w[i]; j--)
				dp[j] = min(dp[j], dp[j - w[i]] * p[i]);

		printf("%.1lf%%\n", (1.0 - dp[M])*100.0);      // 怎么输出'%'?  "%%"
	}

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值