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;
}
posted @ 2012-11-03 19:32  kedebug  阅读(382)  评论(0编辑  收藏  举报