POJ 1018 Communication System dp

Communication System
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 23065   Accepted: 8197

Description

We have received an order from Pizoor Communications Inc. for a special communication system. The system consists of several devices. For each device, we are free to choose from several manufacturers. Same devices from two manufacturers differ in their maximum bandwidths and prices.
By overall bandwidth (B) we mean the minimum of the bandwidths of the chosen devices in the communication system and the total price (P) is the sum of the prices of all chosen devices. Our goal is to choose a manufacturer for each device to maximize B/P.

Input

The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the number of test cases, followed by the input data for each test case. Each test case starts with a line containing a single integer n (1 ≤ n ≤ 100), the number of devices in the communication system, followed by n lines in the following format: the i-th line (1 ≤ i ≤ n) starts with mi (1 ≤ mi ≤ 100), the number of manufacturers for the i-th device, followed by mi pairs of positive integers in the same line, each indicating the bandwidth and the price of the device respectively, corresponding to a manufacturer.

Output

Your program should produce a single line for each test case containing a single number which is the maximum possible B/P for the test case. Round the numbers in the output to 3 digits after decimal point.

Sample Input

1 3
3 100 25 150 35 80 25
2 120 80 155 40
2 100 100 120 110

Sample Output

0.649


題目大意:

有n個設備,每個設備有m個選擇,每個選擇具有兩種不同屬性,一個是帶寬b,一個是價格p。

求選好n種設備,使得所選設備中最小的b除以“p的總和”的值最大


下面是自己的ac代碼

裏面都有註釋說明了

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <memory>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <functional>
#define maxn 1000005
#define mod 100007

using namespace std;
typedef unsigned long long ll;
int b[105][105],p[105][105];
int num[105];
int dp[105][105*105];
//dpij,i表示當前遍歷到了第i個商品,j表示所能選擇的最小帶寬
//dp值爲當前已選擇的所有商品價格除以最小的廠商帶寬
//在dp到i時,對於i-1時的每一個狀態(j取不同的值),
//都用其(dp[i-1][j])遍歷一遍第i個商品的所有廠商,
//並且求出每一個j對應的最小 “總和p”



int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        vector<int> g[105];
        //vector用於減少運行時間,因爲第二個下標會有很大冗餘
        //很多值不必遍歷,可以將i-1時出現的j值記錄下來,
        //到i後直接使用
        memset(b,0,sizeof(b));
        memset(p,0,sizeof(p));
        memset(dp,-1,sizeof(dp));
        memset(num,0,sizeof(num));
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i+=1){
            scanf("%d",&num[i]);
            for(int j=0;j<num[i];j+=1){
                scanf("%d %d",&b[i][j],&p[i][j]);    //第i個商品第j個廠商的信息
                if(i==0){
                    dp[0][b[i][j]]=p[i][j];
                    g[0].push_back(b[i][j]);       //爲了減小時間,可以用一個vector來記錄存在的
                }
            }
        }

        float ans=0.0;
        for(int i=1;i<n;i+=1){
            int sz=g[i-1].size();
            for(int j=0;j<sz;j+=1){
                for(int k=0;k<num[i];k+=1){
                    int minb=min(g[i-1][j],b[i][k]);
                    if(dp[i][minb]==-1){
                        //如果等於-1證明這個值時第一次更新到,因爲是求最小值,
                        //所以這時不可以直接使用min來對比,直接賦值即可
                        dp[i][minb]=dp[i-1][g[i-1][j]]+p[i][k];
                        g[i].push_back(minb);
                    }
                    else{
                        //如果不等於-1,證明這個最小帶寬值對應的dp值已經更新過
                        //那麼需要找出最小的“總和p”
                        dp[i][minb]=min(dp[i][minb],dp[i-1][g[i-1][j]]+p[i][k]);
                    }
                }
            }

            if(i==n-1){
                for(int j=0;j<g[i].size();j+=1){
                    ans=max(ans,(float)g[i][j]/(float)dp[i][g[i][j]]);
                }
            }
        }

        if(n==1){
            for(int i=0;i<g[0].size();i+=1){
                ans=max(ans,(float)g[0][i]/(float)dp[0][g[0][i]]);
            }
        }
        printf("%.3f\n",ans);
    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章