POJ 1018 Communication System(分组背包DP)

和普通的分组DP还是有点差别的,要求背包容量固定的变化,而非1->V之类的

现在渐渐理解分组背包,1. 每组最多选择一个 2. 每组选择一个 ,这两类的差别就是在与dp数组的初始化问题

#include <cstdio>

#include <cstdlib>

#include <cstring>



#define min(a,b) (((a) < (b)) ? (a) : (b))

#define max(a,b) (((a) > (b)) ? (a) : (b))



int dp[101][1005]; // dp[i][j] 第i组,当波特为j的时候,最小花费



int main()

{

    int cases, n;

    scanf("%d", &cases);

    while (cases--)

    {

        scanf("%d", &n);

        int b[105], p[105];

        int m;

        int maxb = -1;

        for (int i = 0; i < n; ++i)

        {

            for (int j = 0; j < 1005; ++j)

                dp[i][j] = 1e9;



            scanf("%d", &m);

            

            for (int j = 0; j < m; ++j)

            {

                scanf("%d %d", &b[j], &p[j]);

                if (maxb < b[j])

                    maxb = b[j];

            }

            if (i == 0)

            {

                for (int j = 0; j < m; ++j)

                    if (dp[i][b[j]] > p[j])

                        dp[i][b[j]] = p[j];

                continue;

            }

            for (int j = 0; j <= maxb; ++j)

            {

                if (dp[i-1][j] == 1e9)

                    continue;

                for (int k = 0; k < m; ++k)

                {

                    int tb = min(j, b[k]);

                    dp[i][tb] = min(dp[i][tb], dp[i-1][j] + p[k]);

                }

            }

        }

        double ans = 0;

        for (int j = 0; j <= maxb; ++j)

            if (dp[n-1][j] != 1e9)

                ans = max(ans, 1.0 * j / dp[n-1][j]);

        printf("%.3lf\n", ans);

    }



    return 0;

}

你可能感兴趣的:(System)