poj1018

首先会定义一个状态dp[i]来表示处理第i件物品,然而第i件物品的转移要依据前面的物理,会违背无后效性的原则,所以还需要增加定义一个状态来表示处理第i件物品时前i - 1件物品的最小带宽。
 那么dp[i][j]应该代表什么呢?一开始已经想到了前面二维状态的代表,而没有想到dp[i][j]应该代表什么。而应该的想法是既然最小带宽已经被表示了,为了求到最大的B / P的话,B是已经知道的。所以我们
 应该使dp[i][j]代表处理第I件物品,最小带宽为j的最小总价格,因为最小带宽只能够从输入设备那里面得到,所以还需要用dp[i][j] = -1来表示没有该最小带宽。那么状态方程就可以表示成dp[i][j] = min(dp[i - 1][k] + price[k]) (其中dp[i - 1][k]因该首先
 是可以达到的,然后可以达到之后,进行状态的转移,可以转到dp[i][k],如果第m件产品的带宽比该最小带宽大,或者是转移到dp[i][min],表示第m件产品的带宽比最小带宽小)。最后枚举所有可能的最小带宽,求

 其中的最大值。


#include <stdio.h>
#include <string.h>


#define MAX_NUMBER 105
#define MAX_BANDWIDTH 10005
#define min(a, b) ((a) > (b))?(b) : (a)
#define max(a, b) ((a) > (b))?(a) : (b)

int dp[MAX_NUMBER][MAX_BANDWIDTH];
int bandwidth[MAX_NUMBER];
int price[MAX_NUMBER];


int main() {

    int test_case;
    int i, j, k, device_number, manufacture, max_bandwidth, min_number;
    double ans, temp;
    scanf("%d", &test_case);
    while (test_case--) {
        memset(dp, -1, sizeof(dp));
        scanf("%d", &device_number);
        max_bandwidth = 0;
        for (i = 1; i <= device_number; i++) {
            scanf("%d", &manufacture);
            for (j = 0; j < manufacture; j++) {
                scanf("%d%d", &bandwidth[j], &price[j]);
                if (bandwidth[j] > max_bandwidth) {
                    max_bandwidth = bandwidth[j];
                }
            }
            if (i == 1) {
                dp[i - 1][max_bandwidth] = 0;
            }
            for (j = 1; j <= max_bandwidth; j++) {
                if (dp[i - 1][j] != -1) {
                    for (k = 0; k < manufacture; k++) {
                        min_number = min(j, bandwidth[k]);
                        if (dp[i][min_number] != -1) {
                            dp[i][min_number] = min(dp[i][min_number], dp[i - 1][j] + price[k]);
                        }
                        else {
                            dp[i][min_number] = dp[i - 1][j] + price[k];
                        }
                    }
                }
            }
        }
        ans = 0;
        for (j = 1; j <= max_bandwidth; j++) {
            if (dp[device_number][j] != -1) {
                temp = 1.0 * j / (dp[device_number][j]);
                if (temp > ans) {
                    ans = temp;
                }
            }
        }
        printf("%.3lf\n", ans);
    }
}


你可能感兴趣的:(poj1018)