Link:http://acm.hdu.edu.cn/showproblem.php?pid=1203
Problem:
I NEED A OFFER!
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 16871 Accepted Submission(s): 6739
后面的m行,每行都有两个数据ai(整型),bi(实型)分别表示第i个学校的申请费用和可能拿到offer的概率。
输入的最后有两个0。
10 3 4 0.1 4 0.2 5 0.3 0 0
44.0%HintYou should use printf("%%") to print a '%'.
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
double f;
double fp;
double p;
}a[10011];
bool cmp(node a,node b)
{
return a.p<b.p;
}
int main()
{
int n,m,i;
double ans,pp;
while(scanf("%d%d",&n,&m)==2)
{
if(n==0&&m==0)
break;
for(i=1;i<=m;i++)
{
scanf("%lf%lf",&a[i].f,&a[i].fp);
a[i].fp=1-a[i].fp;
a[i].p=a[i].fp/a[i].f;
}
sort(a+1,a+m+1,cmp);
pp=1;
for(i=1;i<=m;i++)
{
if(n>=a[i].f)
{
n-=a[i].f;
pp*=a[i].fp;
}
if(n==0)
break;
}
ans=1-pp;
printf("%.1lf%%\n",ans*100);
}
return 0;
}
附上另一种做法:(0-1背包dp实现)
以下代码来自:http://blog.163.com/wuguojin03@126/blog/static/17154113120109311346887/
状态:f[j]:投了j元不能获得一个offer的最小概率状态转移:f[j]=min{f[j],f[j-cost[i]]*(1-per[i])}初始值:f[]为1源代码:#include<iostream> using namespace std; int main() { int n,m,i,j,cost[1001]; double per[1001],f[10001]; //f[j]:投了j元不能获得offer的最小概率 while(scanf("%d%d",&n,&m)&&(n!=0 || m!=0)) { for(i=0;i<m;i++) scanf("%d%lf",&cost[i],&per[i]); for(i=0;i<=n;i++) f[i]=1; for(i=0;i<m;i++) for(j=n;j>=cost[i];j--) if(f[j]>f[j-cost[i]]*(1-per[i]))//注意这点是选小的 f[j]=f[j-cost[i]]*(1-per[i]); printf("%.1lf%%\n",(1-f[n])*100); } return 0; }