POJ 1018. Communication System 动态规划解法

题意简述:

有n种设备,每种设备有m种生产商可以选择,每个生产商制造的设备带宽和价格不同

令B为所有选择的设备的最小带宽,P为所有选择的设备的价格之和

为每个设备选择生产商使得B/P最大


实现:

#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
#define inf 1000000

int min(int a, int b) {
	return a < b ? a : b;
}

int main(void) {
	int cases_num;
	cin >> cases_num;
	while (cases_num--) {
		int devices_num, max_bandwidth = 0;
		cin >> devices_num;
		vector<vector<int> > b(devices_num), p(devices_num);
		vector<int> devices_choices; //保存每个设备有多少种不同类型

		for (int i = 0; i < devices_num; i++) {
			int choices_num;
			cin >> choices_num;
			devices_choices.push_back(choices_num);

			int bandwidth, price;
			for (int j = 0; j < choices_num; j++) {
				cin >> bandwidth >> price;
				if (bandwidth > max_bandwidth) max_bandwidth = bandwidth;
				b[i].push_back(bandwidth);
				p[i].push_back(price);
			}
		}
		
		//dp[i][j]: 前i个(从0开始)设备的最大带宽为j时的最小价格
		vector<vector<int> > dp(devices_num, vector<int>(max_bandwidth + 1, inf));

		for (int i = 0; i < devices_num; i++) {
			for (int j = 0; j <= max_bandwidth; j++) {
				for (int m = 0; m < devices_choices[i]; m++) {
					if (j <= b[i][m]) {
						if (i == 0) 
							dp[i][j] = min(p[0][m], dp[0][j]);
						else 
							dp[i][j] = min(dp[i - 1][j] + p[i][m], dp[i][j]);
					}			
				}
			}
		}

		double maxValue = 0;
		for (int j = 0; j <= max_bandwidth; j++) {
			if ((double)j / (double)dp[devices_num - 1][j] > maxValue)
				maxValue = (double)j / (double)dp[devices_num - 1][j];
		}

		cout << fixed << setprecision(3) << maxValue << endl;
	}
}

简单测试样例:

3
3
3 100 25 150 35 80 25
2 120 80 155 40
2 100 100 120 110
3
3 130 35 140 33 90 25
2 300 80 195 45
2 100 50 120 110
4
5 130 35 140 33 90 25 300 80 195 45
5 1300 135 1400 383 980 205 3080 890 1095 445
4 1200 135 400 383 980 205 308 890
2 1400 900 2400 1000


输出结果:

0.649
0.781
0.240



你可能感兴趣的:(C++,动态规划,poj)