题意: 你要写一个社交系统 需要n个零件 你由n个开发商 每个开发商提供 w个零件给你 你可以从每个开发商那拿一个零件 有一个宽带值 和 价格
使得最后的性价比(B/P) 最高
B 为你选择的n个零件中的min P 为你选择n个零件的总和
思路: 当 b 值 一定的情况使得性价比最高 我们只需要求得 选择n个零件的最小值 dp【i】 = min dp【i-1】+p,dp【i】
当b不定的时候
当b不定的时候 我们设 dp【i】【j】 为选i个零件到达 j宽带的最大值
k 为 其他宽带的值
dp【i】【j】 = min(dp【i-1】【j】,dp【i-1】【k】 +p);
样例:
1 3 3 100 25 150 35 80 25 2 120 80 155 40 2 100 100 120 110150 35
155 40
120 110
120/185=0.649
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<stdlib.h>
using namespace std;
const int inf = 0xffffff;
int t;
int dp[105][1005];
int a[105];
int main()
{
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i = 0 ; i <= n; i++)
for(int j = 0 ; j <= 1005; j++)//初始化 动态ps:初始化的细节问题 一种问法是恰好装好背包 f【0】]=0 f【1~n】设置为-~(无穷) 这样可以保证最终的到de f【n】为一种
dp[i][j] = inf;<pre name="code" class="cpp">/*恰好装满背包的最优解 反之依然 背包九讲*/
int b,p;
//宽带 和 价格
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
for(int j = 1; j <= a[i]; j++)
{
scanf("%d%d",&b,&p);
if(i==1) dp[1][b] = min(dp[1][b],p);
else
{
for(int k = 0; k < 1005; k++)
{
if(dp[i-1][k] != inf)
{
if(k<=b)
{
dp[i][k] = min(dp[i][k],dp[i-1][k] + p);
}
else
{
dp[i][b] = min(dp[i][b],dp[i-1][k] + p);
}
}
}
}
}
}
double ans = 0.0;
for(int i = 0; i < 1005; i++)
{
if(dp[n][i] != inf)
{
double ret = i*1.0 / dp[n][i];//注意1.0 double 细节
if(ret > ans) ans = ret;
}
}
printf("%.3lf\n",ans);
}
}
int b,p;//宽带 和 价格 for(int i=1; i<=n; i++) { scanf("%d",&a[i]); for(int j = 1; j <= a[i]; j++) { scanf("%d%d",&b,&p); if(i==1) dp[1][b] = min(dp[1][b],p); else { for(int k = 0; k < 1005; k++) { if(dp[i-1][k] != inf) { if(k<=b) { dp[i][k] = min(dp[i][k],dp[i-1][k] + p); } else { dp[i][b] = min(dp[i][b],dp[i-1][k] + p); } } } } } } double ans = 0.0; for(int i = 0; i < 1005; i++) { if(dp[n][i] != inf) { double ret = i*1.0 / dp[n][i];//注意1.0 double 细节
if(ret > ans) ans = ret; } } printf("%.3lf\n",ans); }} 贪心解法 :
思路就简单多了 每次选性价比最高的那个
poj 友情提供
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct node
{
int bandwidth, price, kind;
};
node divice[10001];
int num[101];
bool cmp( node a, node b )
{
if ( a.bandwidth < b.bandwidth )
return true;
else if ( a.bandwidth == b.bandwidth )
{
if ( a.price < b.price )
return true;
else if ( a.price == b.price )
{
if ( a.kind < b.kind )
return true;
else
return false;
}
else
return false;
}
else
return false;
}
int main()
{
int testNumber;
scanf("%d", &testNumber);
for ( int testCount = 1 ; testCount<= testNumber ; testCount ++ )
{
int number;
scanf("%d", &number);
int count = 0;
int maxWidth[101];
for ( int i = 0 ; i < number ; i ++ )
maxWidth[i] = 0;
for ( int i = 0 ; i < number ; i ++ )
{
scanf("%d", &num[i]);
for ( int j = 0 ; j < num[i] ; j ++ )
{
scanf("%d%d", &(divice[count].bandwidth), &(divice[count].price));
divice[count].kind = i;
if ( divice[count].bandwidth > maxWidth[i] )
maxWidth[i] = divice[count].bandwidth;
count ++;
}
}
sort( divice, divice+count, cmp );
int minMaxWidth = 9999999;
for ( int i = 0 ; i < number ; i ++ )
{
if ( maxWidth[i] < minMaxWidth )
minMaxWidth = maxWidth[i];
}
double maxResult = 0;
for ( int i = 0 ; i < count - number + 1 ; i ++ )
{
int minPrice[101];
for ( int j = 0 ; j < number ; j ++ )
{
minPrice[j] = 9999999;
}
int tempBandwidth = divice[i].bandwidth, tempPrice = divice[i].price, tempKind = divice[i].kind;
for ( int j = i + 1 ; j < count ; j ++ )
{
if ( divice[j].kind != tempKind && divice[j].price < minPrice[divice[j].kind] )
minPrice[divice[j].kind] = divice[j].price;
}
for ( int j = 0 ; j < number ; j ++ )
{
if ( j != tempKind )
tempPrice += minPrice[j];
}
if ( maxResult < (double)tempBandwidth/tempPrice )
maxResult = (double)tempBandwidth/tempPrice;
}
printf("%.3f\n", maxResult);
}
}