POJ-1018 Communication System(dp)
题目描述
有 \(n(1\leq n \leq 100)\) 种设备,每种设备有 \(c_i(1\leq c_i\leq 100)\) 个厂家生产,设备 \(i(1\leq i\leq n)\) 的第 \(j(1\leq j\leq c_i)\) 个厂家生产的设备会存在两个方面的差别:参数 \(a_{ij}\) 和价格 \(b_{ij}\)。
现在每种设备都需要 \(1\) 个,设 \(\min\) 为选出的 \(n\) 件设备中的最小参数,\(\text{sum}\) 为选出的 \(n\) 件设备的总价格,求 \(\frac{\min}{\text{sum}}\) 的最大值。
分析
设 \(dp[i][j]\) 为对于前 \(i\) 件物品,参数最小值为 \(j\) 的价格总和;对于前 \(i-1\) 件物品,设参数的最小值为 \(k\)。
当 \(j\leq k\) 时,\(dp[i][j]=\min(dp[i][j],dp[i-1][k]+b_{ij})\)。
当 \(j>k\) 时,\(dp[i][k]=\min(dp[i][k],dp[i-1][k]+b_{ij})\)。
转移的时候从 \(0\) ~ \(2000\) 枚举最小参数 \(j\);最后求答案的时候,枚举 \(i\in[0,2000]\),求 \(i/dp[n][i]\) 的最大值。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int c[110],a[110][110],b[110][110];
int dp[120][2010];
int main()
{
int T;
cin>>T;
while(T--)
{
memset(dp,0x3f,sizeof(dp));
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&c[i]);
for(int j=1;j<=c[i];j++)
scanf("%d %d",&a[i][j],&b[i][j]);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=c[i];j++)
{
if(i==1)
dp[1][a[1][j]]=min(dp[1][a[1][j]],b[1][j]);
else
{
for(int k=0;k<=2000;k++)
{
if(dp[i-1][k]!=0x3f)
{
if(a[i][j]<=k)
dp[i][a[i][j]]=min(dp[i][a[i][j]],dp[i-1][k]+b[i][j]);
else
dp[i][k]=min(dp[i][k],dp[i-1][k]+b[i][j]);
}
}
}
}
}
double ans=0.0;
for(int i=0;i<=2000;i++)
if(dp[n][i]!=0x3f)
ans=max(ans,1.0*i/dp[n][i]);
printf("%.3f\n",ans);
}
return 0;
}
posted on 2020-11-06 18:17 DestinHistoire 阅读(75) 评论(0) 收藏 举报
浙公网安备 33010602011771号