动态规划入门(dp):杭电OJ1203

 本题是一个简化的01背包的问题

解决动态规划的问题的步骤大致可以分为三种:

一,理解dp的含义

二,推理出递推公式

三,找出初始值。

下面来分析这一道题目:

一,理解dp的含义:在这里设成dp[i],意思是当经费为 i 时最小的失败的概率

二,推理出递推公式:先把递推公式给出  dp[j] = min(dp[j],dp[j - w[i] ] * p[i]);下面来分析一下这个公式,dp[j] 是在 不拿第 i 个学校  和 拿了第 i 个学校之间作比较。如果不拿第 i 个学校,则依然是dp[j],反之,如果拿了第i个学校,那么这个就是在 经费为 j - w[i]时的时候的最小的失败的概率上 乘以这个学校失败的概率(当然是要在经费充足的情况下才可以),之后二者在相互比较,取其最小值即可。

三,本题之后定义初始值全部为 1 ,因为如果不选任何一个学校的失败的概率为 1.

看到这里,读者可能还是对这个问题理解不是很清楚,下面通过具体的代码,和草稿来帮助读者理解

#include<iostream>
#include<iomanip>
using namespace std;
#define min(x,y) x<y?x:y
const int MAXN = 10005;
int main()
{
	int n,m;
	int i ,j ,w[MAXN];
	double p[MAXN],dp[MAXN];//记住这里的p数组是失败的概率,dp[i]的意思是在经费为x万元的时候选择该学校失败的概率 
	while(cin>>m>>n)
	{
		if(m == 0& n == 0)
		break;
		//memset(dp,1,sizeof(dp));//全部初始化为1 
		//cout<<dp[1]<<endl;
	
		for(i =0;i<n;i++) 
		{
			cin>>w[i];
			cin>>p[i];
			p[i] = 1-p[i];//这里代表的是失败的概率 
		}
		for(i =0;i<=m;i++)
		dp[i] = 1;
		for(i =0;i<n;i++)
		for(j = m;j >= w[i];j--)
		{
			dp[j] = min(dp[j],dp[j-w[i]]*p[i]);
		}
		cout<<fixed<<setprecision(1)<<100*(1-dp[m])<<"%"<<endl;
	}
}

并从此依次往后类推。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值