DestinHistoire

 

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)    收藏  举报

导航