描述
每组测试数据占3行,第1行是一个正整数w (1 <= w <= 10000),表示口袋承重上限。第2行是一个正整数s (1 <= s <=100),表示金属种类。第3行有2s个正整数,分别为n 1, v 1, n 2, v 2, ... , n s, v s分别为第一种,第二种,...,第s种金属的总重量和总价值(1 <= n i <= 10000, 1 <= v i <= 10000)。
2 50 4 10 100 50 30 7 34 87 100 10000 5 1 43 43 323 35 45 43 54 87 43
171.93 508.00
题目瞎逼逼了那么多,其实实质就是部分背包问题,本以为很简单,一道水题,可调了半天,临近崩溃的边缘,终于AC,大家见笑了。问题是一个很智障的问题,大家一定要记住,我们定义 int a,b;float c;尽管c为实型,但是a/b时一定回取整,因此a,b,c应该都定义为float。
代码如下:
#include <cstdio>
#include <cstring>
using namespace std;
double a[1001],w[1001],v[1001];
void qsort(int l,int r)
{
double mid=0,p=0;
int i,j;
i=l;j=r;mid=a[(l+r)/2];
while(i<=j)
{
while(a[i]>mid) ++i;
while(a[j]<mid) --j;
if(i<=j)
{
p=a[i];a[i]=a[j];a[j]=p;
p=w[i];w[i]=w[j];w[j]=p;
p=v[i];v[i]=v[j];v[j]=p;
++i;--j;
}
}
if(i<r) qsort(i,r);
if(l<j) qsort(l,j);
}
int main()
{
double valu=0,total;
int n,k;
scanf("%d",&k);
while(k--)
{
scanf("%lf",&total);
scanf("%d",&n);
memset(a,0,sizeof(a));
for(int i=1;i<=n;++i)
{
scanf("%lf%lf",&w[i],&v[i]);
a[i]=v[i]/w[i];
}
qsort(1,n);
int i=0;
while(total>0&&i<n)
{
++i;
if(total-w[i]>=0)
{
total-=w[i];
valu+=v[i];
}
else
{
valu+=total*a[i];
break;
}
}
printf("%0.2lf\n",valu);
valu=0;
}
}
标准的部分背包,做题不能眼高手低啊
最后,尽量快排还是手写,不要调STL库,这样虽然费点事,但是好操作。