hdu1203

本文探讨了在解决背包问题时,贪心算法的局限性及其与正确解决方案之间的差距。通过一个具体示例,展示了贪心策略在某些情况下无法得到最优解,并给出了使用动态规划方法的正确解答。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ContractedBlock.gifExpandedBlockStart.gifView Code
//从反面考虑:就是一个offer都没获得,最后结果p=1-p;
#include"iostream"
#include
"algorithm"
using namespace std;
struct offer
{
int a;
double b;
}s[
10000];

int cmp(offer x, offer y)
{
return x.b>y.b;
}
int main()
{
int n,m;
int i;
while(cin>>n>>m,n+m)
{

for(i=0;i<m;i++)
scanf(
"%d %lf",&s[i].a,&s[i].b);

sort(s,s
+m,cmp);

int sum=0;
double p=1.0;

for(i=0;i<m;i++)
{
if(s[i].a+sum<=n)
{
sum
+=s[i].a;
p
*=(1-s[i].b);
}
}
p
=(1-p)*100;
printf(
"%.1lf%%\n",p);
}
return 0;
}

这题有漏洞啊!应该是属于背包问题,贪心也不可能这么容易过啊!

不多解释,看错误的一种情况:

sample:

>10  4

>5 0.4

>4  0.3

>3  0.2

>2  0.2

很明显 P2+P3=0.4>P4=0.3

而运行结果为:58.0%

正确结果:61.6%

所以此题还是选择背包算法求解好!

ContractedBlock.gifExpandedBlockStart.gifView Code
#include"iostream"
using namespace std;
double dp[100001];
struct node
{
int a;
double b;
}s[
1001];

double Max(double a ,double b)
{
return a>b?a:b;
}

int main()
{
int n,m;
int i,j;
while(cin>>n>>m,n+m)
{
for(i=0;i<m;i++) scanf("%d %lf",&s[i].a,&s[i].b);

memset(dp,
0.0,sizeof(dp));

for(i=0;i<m;i++)
{
for(j=n;j>=s[i].a;j--)
{
dp[j]
=Max(dp[j] , 1-(1-dp[j-s[i].a])*(1-s[i].b));
}
}
double p=dp[n]*100;
printf(
"%.1lf%%\n",p);
}
return 0;
}

转载于:https://www.cnblogs.com/FCWORLD/archive/2011/04/22/2025229.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值